views:

56

answers:

1

I need to design and implement something similar to what Martin Fowler calls the "Unit of Work" pattern. I have heard others refer to it as a "Shopping Cart" pattern, but I'm not convinced the needs are the same.

The specific problem is that users (and our UI team) want to be able to create and assign child objects (with referential integrity constraints in the database) before the parent object is created. I met with another of our designers today and we came up with two alternative approaches.

a) First, create a dummy parent object in the database, and then create dummy children and dummy assignments. We could use negative keys (our normal keys are all positive) to distinguish between the sheep and the goats in the database. Then when the user submits the entire transaction we have to update data and get the real keys added and aligned.

I see several drawbacks to this one.

  • It causes perturbations to the indexes.
  • We still need to come up with something to satisfy unique constraints on columns that have them.
  • We have to modify a lot of existing SQL and code that generates SQL to add yet another predicate to a lot of WHERE clauses.
  • Altering the primary keys in Oracle can be done, but its a challenge.

b) Create Transient tables for objects and assignments that need to be able to participate in these reverse transactions. When the user hits Submit, we generate the real entries and purge the old.

I think this is cleaner than the first alternative, but still involves increased levels of database activity.

Both methods require that I have some way to expire transient data if the session is lost before the user executes submit or cancel requests.

Has anyone solved this problem in a different way?

Thanks in advance for your help.

+1  A: 

I don't understand why these objects need to be created in the database before the transaction is committed, so you might want to clarify with your UI team before proceeding with a solution. You may find that all they want to do is read information previously saved by the user on another page.

So, assuming that the objects don't need to be stored in the database before the commit, I give you plan C:

Store initialized business objects in the session. You can then create all the children you want, and only touch the database (and set up references) when the transaction needs to be committed. If the session data is going to be large (either individually or collectively), store the session information in the database (you may already be doing this).

Jon Seigel
Hi,appartently I though about using sessions in the first, which would, however, be rather tricky to implement.Suppose I am saving an object, like a Newspaper Article, which will have a number of attachments linked to it. The attachments are also objects themselves, and they should also be accessible outside of the domain of the Newspaper Article. How do I tell the article what image IDs to reference to, when the transaction has not even yet begun?
clops
"The attachments are also objects themselves, and they should also be accessible outside of the domain of the Newspaper Article." -- Does this mean other users need access to these objects? "How do I tell the article what image IDs to reference to, when the transaction has not even yet begun?" -- They would be associated in some other programmatic way (i.e., each article contains a collection of images, and that information is stored in the session). The actual IDs and references would not be physically established in the database until everything goes in at once.
Jon Seigel