0

Lets say, for example, I have a widget ordering application. It allows customers to order from a catalog of widgets. Obvious object choices might be 'Catalog' and 'Orders'. The 'Catalog' object will allow me to browse, add and delete widgets. The 'Orders' object will allow me to create and update orders.

They are both multi-thread safe and handle object locking and database transactions internally. They are nicely encapsulated/compartmentalized -- until a requirement comes along that says when a widget is deleted from the catalog, line items containing that widget must be deleted from existing orders.

A common way to handle this scenario is with the observer pattern. In other words, an event is raised from 'Catalog' when part is deleted. A mediator then handles this event and tells 'Orders' to remove line items with that widget.

The pros: preserves encapsulation, loose coupling.

The cons: are not the removal of the part and the update of the orders a single, atomic operation? This technique would violate that. In other words, if an error happens handling the event, the part may be removed without ever updating any orders.

I am favoring the cons. However, this can only mean that another object is required -- one that aggregates 'Catalog' and 'Orders', and causes both operations to be performed atomically. The problem is each object performs object locking and database transactions, neither of which I can see how to cleanly extract -- ie, technically the new object should handle that responsibility now because you cannot lock objects and perform transactions twice and still have an atomic operation.

Thoughts? Is this a classic problem I've not seen before? I've been down the Spring road but I don't think there's anything AOP can do here.

Thanks.

Dan
  • 1
  • 1

1 Answers1

-1

This is a link describing how deletes and updates are handled/cascaded for different types of relationship under GORM. It appears that the setup you have described could be modeled as a few 1:m or m:n relationships. Ctrl+F for "cascading" and this should shed some light on how changes between relationships are handled and how to best model the relationships. As far as errors are concerned, cascading also helps take care of these given you provide the correct "belongsTo" relationships. If you want to delete or change a parent object, the children must first be deleted/updated as well. If the changes made to the children fail, the original call fails, and no changes are persisted to the database. When the documentation refers to "saving" after making a change, it refers to permanent changes, which, given a set of relationships, can only be performed under certain circumstances, such as child objects having been deleted first by the cascade. Sorry I can't give you a direct answer as I'm not sure if you're trying to change your model style or implement your own relational model, but hopefully this helps you out a bit. GORM should be thread safe as far as I remember. Go to the very top and read through the entire "5. Object Relational Mapping (GORM)" section. Good luck!

  • I think his question is more about cross-cutting concerns for components, not the data of immediate parent-child relations. For example, if you DID have cascading deletes, what if you had to perform some cross-cutting operation based on the deletion of child objects. A notification would need to be raised. However, because the concern is cross-cutting it doesn't feel right to include those actions as part of the same atomic operation. That introduces the issue he mentions, that this lack of atomicity introduces potential data inconsistencies caused by other failures. – Matt H Apr 12 '11 at 23:33