Concurrent Modification

The TMCore API does not provide any explicit transaction control methods. Instead, the TMCore system allows concurrent access using an optimistic locking strategy. Under this strategy data is loaded from the TMCore database without locking the rows in the database (allowing any other application to concurrently access the data). Only when the data is saved back to the database, is the database checked to ensure that no other application modified the data in the intervening time. If a modification did take place (known as a concurrent modification), a ConcurrentModificationException is raised and the updates that were attempted will be aborted. When a call to ITopic.Save(), IAssociation.Save() or ITopicMap.Save() is made, all changes to the object on which the Save() method was invoked and all contained objects will be committed to the database in a single transaction. This means that a call to Save() will either succeed completely or fail without modifying the database.

To minimize the chances of and the impact of concurrent modification, it is strongly recommended that you tailor the commit strategy for your application to the expected write patterns against the topic map. If you anticipate frequent writes from multiple separate threads, then try to keep the number of changes between calls to the Save() method as small as possible. This strategy will maximise the interleaving between applications and minimize the amount of work you need to redo in the case of a ConcurrentModificationException. If you anticipate only infrequent writes or if you can isolate writes to one thread or if you can isolate writer threads in a way that would prevent them from writing the same objects in the topic map, then you can afford to make more updates to the topic map between calls to Save().

From TMCore05 SP2, the ITopic and IAssociation interfaces both support a method named Reload(). This method can be used to update an ITopic or IAssociation instance from the database, overwriting any local modifications with the most recent version of the object from the persistent store. To recover from a ConcurrentModificationException therefore, you must first invoke the Reload() method on the locally modified object, then reapply any local modifications and finally invoke the Save() method to save your changes to the persistent store.