In a recent talk I spoke a lot about making transactional assumptions explicit. It didn't use that exact wording, but expressed the idea. The transactions I am talking about are logical transactions, not RDBMS transactions. The two tend to be closely related, but are definately not identical.
Recently I have been providing a transaction interface akin to a JTA transaction style interface (but not JTA, and not to act as a 2-phase monitor type doohickey =) at the web tier. Its role is to store logical transactional state:
The basic design is stolen directly from JTA/JTS, but with an API designed for the problems I am addressing, not the general solution (ie, much simpler api for simpler problem). The primary piece of it is a SerializableTransaction
and associated ResourceAdaptors
. The gist is that any state associated with the logical transaction is attached to a specific transaction instance (they accept attributes a la an HttpSession
or other context) and any resource which needs to be treated as a long-running transaction can be attached via a ResourceAdaptor
.
Everything held by the tx needs to be serializable (so that it can be offloaded, say on session migration or replication). The resource adaptors come in on passivation/activation. They need to be able to re-establish transactional state for attributes which need it. An example would be to use a known-name attribute for storing the currently acted upon object graph. On passivation a JDO2ResourceAdaptor
could detach them, then on activation attach them (and make them transactional again).
This particular example is useful because it effectively gives you optimistic checks on each activate/passivate cycle instead of just on commit -- detect optimistic failures early!
The technique also allows for a generalization of another common problem -- session timeout. An in-progress transaction can be serialized out to a blob and brought back in on the next session for that user. Boom =)
Finally, it solves another big problem -- better session attribute management. Attaching attributes to the transaction allows them to be flushed on transaction commit/abort rather than remembering to pull everything out of the session when you finish the logical transaction. In a lot of ways it is like having automatic memory management instead of manual, but with scopes declared in application flow instead of lexically.
Explicit guud.