Hi Dave. I think your proposal would be useful to have in Clojure, I
have thought about something similar since I read about the STM. But I
also think there are quite a few difficulties in implementing this in
a "sane" way. Actually, the more I think about it, the more it seems
that the goal of STM (to aid concurrent programming at a micro-level)
is not really compatible with that of traditional transactions (to
enable persistent and consistent changes to a shared resource, at an
application/system level). Here are some observations:
1. Normal transactions
A successful commit on an external transaction can be (and usually is)
a side-effect, so it breaks the assumption that transactional
operations are side-effect free and can be retried by the STM. Thus
Clojure would need to recognize this as a special case and treat it as
a "composite" transaction, which can not be retried entirely. I don't
know how STM is implemented in Clojure. Maybe if the external commit
can be delayed until the end of the transaction, when it is certain
that the in-memory operations succeeded, it could work. I think this
is the most promising way of implementing this.
2. XA transactions
If Clojure's STM works similar to an XA transaction, it would still be
difficult to delegate the coordination to a JTA transaction manager.
XA-capable resources MUST have stable storage for crash recovery,
which definitely isn't the case (and also wouldn't make sense) with
the STM. The STM guarantees ACI, external transactions are usually
ACID, so there's a conceptual mismatch between the two. If you think
about it, why would you want to have transactions between a transient
and a durable resource ? Also, XA resources must be prepared to handle
the case of an "heuristic commit", when all resources confirmed the
"prepare" stage, but not the final "commit". This situation does not
exist with pure STM, so one would have to be aware of the risk and
settle for less guarantees when using "composite" transactions.
Razvan.