Background:
Atomicity is one of the mandatory requirements of transactional applications. It is about executing all or nothing, hence most of the times application defines transaction boundaries like,
try {
transaction.begin();
executeTask1();
executeTask2();
executeTask3();
transaction.commit();
} catch (Exception e) {
transaction.rollback();
}
transaction – handle to transaction example, javax.transaction.UserTransaction or java.sql.Connection
This ensures that all tasks are either committed or rolled back, with the help of Transaction Service Provider.
Problem:
Let us first understand the meaning of “Stateful UI Transactions” (I know the nomenclature is confusing enough, but I could not think of anything else).
What if, executing Task 3 (referring to the snippet above) requires manual interference/decision? (Operator wants to validate availability of seats before reserving one). One has to maintain the transaction state across user interactions. In a typical commercial application this would be a Web based GUI or a Windows based client.
Solution:
There can be multiple solutions, database design should consider such a requirement and define flags to indicate transaction status. However, these solutions couple the requirement and data base design tightly.
Other solution that comes into mind is to store the Transaction handle in Session (Either HTTP or Custom Session) and reuse across user interaction to define transaction boundaries. This will not solve our problem, as a transaction handle is always a stateless wrapper over the actual transaction managed by transaction service provide (an application server) .
As recommended a thread of execution realizes a transaction. [Ref: Distributed Transaction Processing: The XA+ Specification Version 2 – page 9]. Most application servers hence implement transactions as a Thread Local Entity.
Now we need to ensure that, the thread that started transaction and executed Task 1 and 2, should execute Task 3 and commit /rollback the transaction.
The pattern models a logical TransactionContext (Object diagram - http://us.f1f.yahoofs.com/bc/42c7f173/bc/Model.jpg?bfTIuNBBTb5fQO0F) , nothing but a Java Thread that begins/commits/rolls back a transaction and executes transactional activities. Client threads assign tasks to the threads executing transactional activities.
Additional thoughts:
Further, application may require to LOCK the data while user interaction. This can be achieved using ISOLATION LEVELS set on connections used to access/modify the data.
Reference Implementation:
I have tried putting together this pattern as a portable framework (http://us.f1f.yahoofs.com/bc/42c7f173/bc/source.jar?bfTIuNBBkXBGqyL7). Would like to receive comments on the same.
Dnyanesh Y. Sonavane