The basic idea of the transaction model is to to ensure that the modification of an object is being handled in an atomic way, At the end of the elaboration a verdict is given whether the transaction has been successful or not. If not, the objects involved in the transactions are restored to the original value before the start of the transaction. In case of success the result of the transaction is updated in the objects.
In the example below we have a string object which can be manipulated by multiple tasks. The methed Begin_Or_Join open the transaction; the method Add is used to associate the object S,U with the transaction and to create a save point.
The operation Cancel rolls all changes which have been done by all tasks. If processing went fine a Commit method is being called. Both the Commit and the Cancel operation will return only after the last process joining this transaction has complete by either committing or canceling the operation.
In the example below first the objects which are subject to transaction management are declared (1). The thread executing the transaction starts with the actual transaction by means of the Begin_Or_Join method (2).
..... T : TID_Type ; begin declare S : String_Object.Object := Create("Hallo Welt"); (1) U : String_Object.Object := Create("Ein String"); begin T := Transaction.Begin_Or_Join; (2) Add(S); (3) Add(U); ..... do something .... if( Some_Error ) (4) Cancel; else Commit; exception when others => Cancel; end; The objects which are taking part in the transaction are added by means of the Add operation (3). These objects are extensions of a base call called TAM.Persistent. In fact the Add creates a backup of the object in memory in case the transaction is being cancelled.
The project is located at https://github.com/merdmann/tam