Transactions and two EOs

Transactions and two EOs

Old forum URL: forums.lhotka.net/forums/t/558.aspx


Bonio posted on Thursday, July 06, 2006

Being a newbie to CSLA.Net, I have run into a problem regarding the interaction between two editable root objects.

What I want to do is as follows:

Object 1 is relates to Inventory (and is uses the DB table 'Inventory')

Object 2 is used for writing a an inventory movement log (using 'InventoryLog' table)

 

\When a change is made to the Inventory object (a Sale or Goods Receive), I would like to

write an entry into the InventoryLog table. Obviously these two actions need to be wrapped in a transaction if one fails. I could do this via a stored proc, but I would like to keep the InventoryLog as an object as it has other uses elsewhere.

Could someone suggest a way in which I could get these two objects to participate in the same transacion?

Thanks

Bonio

Michael Hildner replied on Thursday, July 06, 2006

Hello Bonio,

Take my suggestion with a grain of salt. I'm pretty new to CSLA too, hoping I'm not off base.

I think what you want to do is have Object2 be an editable child object instead of a editable root object. That way your editable root (Object1) can contain an instance of Object2 and when you save Object1, you save your child too.

You may have another class that uses the same table as Object2 that's an editable root, but that would be a different class altogether.

Someone please correct me if I'm wrong.

Regards,

Mike

Wal972 replied on Thursday, July 06, 2006

That would be one way of doing it. Watch that you don't repeat the any busines logic between the two classes

Jurjen replied on Friday, July 07, 2006

Bonio,

One way of doing this is just adding this Logging feature to the Update/Insert Stored Procedure. As I understand it, your Inventory Log is just that, a log, wich I suppose won't change once written to the database. This way it is in the same transaction.

Another way to do this is to create an EditableChild (or Switchable if you also need it as an EditableRoot) and have Object1 create an instance this EditableChild upon Insert/Update and save it in DataPortal_Update/Insert within the same transaction.

Jurjen.

RockfordLhotka replied on Friday, July 07, 2006

You should make sure your objects are designed following the use case. It is rare to have a use case which requires two editable root objects.

But if you convince yourself that this is, in fact, the case, read on...

Your use case, as described, has the requirement of saving multiple objects as a single unit (which again implies a single editable root Smile [:)]), and you can do this with multiple root objects through the use of a Command object.

  1. Create ERO1 and ERO2
  2. The user interacts with ERO1 and ERO2
  3. The user clicks the save button
  4. The save button creates CO1 (a command object) and gives it references to ERO1 and ERO2
  5. The save button then calls CO1.Execute(), which calls DataPortal.Execute(), which calls DataPortal_Execute(), which runs on the server and should be marked as transactional
  6. DataPortal_Execute() calls Save() on ERO1 and ERO2, updating its references to the return values from each Save() call
  7. Back on the client, the save button can get the new ERO1 and ERO2 values from CO1

 

DansDreams replied on Friday, July 07, 2006

Even in Rocky's explanation, the point is that the design should be such that there is one single entity which is aware of the business requirement that those two things be saved together.  It must not simply be represented in the UI's code.  To that end, if the two objects can't be edited separately according to your requirements, you probably want to prevent the public Save() on the two objects and have an internal (friend) method that the command object could use.

DansDreams replied on Friday, July 07, 2006

Reading the original post again more carefully, I think I'd suggest in this specific case that the idea that those are two editable root objects is faulty.  The creation of the log entry is a requirement of the save feature of the inventory BO, and meaningful only in that context.  Unless specifically required for other reasons, I probably wouldn't even consider the logging to be a business object at all, but rather just code that's part of the inventory BO.  You may also want to consider just having a stored procedure for updating inventory that also writes the log entry.

Bonio replied on Friday, July 07, 2006

Having read the responses to my original question, I now realise that my original design was flawed and in fact the Logging role is only a net effect of actions by the Inventory object.

What I will do is to just build logging into the Inventory object rather than have its own separate object.

Many thanks for all the help/advice received.

Bonio

Copyright (c) Marimer LLC