2. Agenda
● What are Distributed Transactions
● Java Distributed Transaction Support
● Transaction Management Models
● XA Transaction Flow
● XA Transaction Optimizations
● XA Transaction Error Handling
● The XA Internals
● Demo
● Recommendations
5. How Java Supports Distributed
Transactions
● Java Transactions API (JTA) implements the X/Open XA
specification
● XA - A system interface which defines how a distributed
transaction should be done
● Mainly used with database drivers and message queues, e.g.
MySQL, Oracle, ActiveMQ etc..
● As per the XA specification, the transaction context is retained in
the current thread context, i.e. all operations of resource
managers must be done in the same thread where the global
transaction started
7. JTA Transaction Manager
● The third party that manages the global transaction
● Resource managers enlist their resources with the transaction
manager
● Transaction manager tracks the resource managers and executes
the two phase commit protocol on behalf of the application
● Popular implementations:-
Bitronix
JBoss JTS
8. Transaction Management Models
● Programmatic Transaction Model (Bean Managed Transactions)
○ Full control of the transaction operations
○ Application has to handle the transaction
start/commit/rollback, and exception handling semantics
○ More error prone, can be hard to manage
● Declarative Transaction Model (Container Managed Transactions)
○ The application server does the transaction handling
○ The application declares/defines how transactions should
behave
○ Less error prone, less boilerplate code, often suitable for
most of the data operations
○ Supported by Spring Framework, JavaEE
9. What do I need to be XA compliant
● Databases (JDBC): A JDBC driver which exposes an XADataSource
implementation
● Messaging (JMS): An XAConnectionFactory for creating XA aware
JMS connections
● In container managed transactions, like in Spring, the
aforementioned entities must be carefully configured in creating
the data sources / connection factories, with the use of a JTA
transaction manager, or else, undesired behavior such as some
operations not rollbacking can happen in failure scenarios
11. Flow of a Distributed Transaction
● A reference to “txManager” mentioned earlier must be of type
javax.transaction.UserTransaction or javax.transaction.TransactionManager
● UserTransaction interface is the application level API exposed to application, while
TransactionManager interface is meant to be used by application servers
● Typically, inside an application server, the UserTransaction and TransactionManager objects can
be looked up by doing a JNDI lookup to a specific resource name. This JNDI resource name is
dependent on the application server vendor, e.g. “java:comp/UserTransaction”. This approach is
mostly used in the programmatic transaction model
● setRollbackOnly method is used to signal the active transaction that, the only outcome of the
global transaction is a rollback, regardless of all the operations that happened/happens
○ A similar approach is used in CMT also, in signalling the application server, that the
ultimate global transaction should rollback, or else, it could be configured for this to
happen is a certain type of an exception is thrown in the middle of a transaction
12. Enlisting XA Resources with the
Transaction Manager
● The XAResources created by each resource manager, must enlist them in the current thread's
transaction context of the transaction manager
● This can be done manually by programmatically enlisting the XAResource objects by looking up
the transaction manager and getting the current thread context
● The manual operation can be error prone, where the user should properly at the right time
should enlist and delist XA resources
● Most of the application servers automatically wraps the RDBMS data sources and JMS
connection factories so it automatically enlist their XAResources with the application server’s
configured transaction manager
○ In other environments, such as when using Spring framework, connection pooling libraries
like DBCP can be used to provide the transaction manager object and wrap an existing
XADataSource datasource to automatically do the enlistment
13. XA Transaction Optimizations
● 1PC Optimization
○ In a distributed transaction, if there is only one resource, the
transaction manager can do a more efficient direct commit,
rather than doing 2PC
● Last Resource Commit Optimization (Last Resource Gambit)
○ Allows you to add a non-2PC support resource to a global
transaction
○ Works by committing the one phase aware transaction at the
end of all prepare operations, and if the commit is successful,
the second phase is executed for all the others
14. XA Transaction Error Handling
● The first phase is executed on all the resource managers to get their promise that, it can
properly commit the transaction later for sure, when the transaction manager tells it
● The transaction manager is suppose to persist the state of the global transaction in the case of a
failure of the client application
○ This would mean, information about the XA resources must be remembered by the
transaction manager, either by making sure the XAResource objects are serializable or else,
have other means of re-creating those objects, e.g. JBoss’s XAResourceRecovery interface
● In the case of the client application crash with the transaction manager, or else, a specific
resource manager fails, after the XA resources objects are recovered, the recover() method on
those are called to retrieve the Xids of those transaction branches in order to continue the 2PC
commit operations
Transaction Manager keeping it promises -> recovery after first phase
15. XA Transaction Error Handling
● HeuristicRollback
○ This exception is thrown by the transaction manager if all the resources participating in the
global transaction made an heuristic decision to rollback, before the transaction manager
could execute the second phase of 2PC. This most probably happens if the resource
manager times out for his second phase execution by the transaction manager
● HeuristicCommit
○ This is the opposite of HeuristicRollback, where all have committed before the transaction
manager executes his second phase decision
● HeuristicMixed
○ This exception is thrown, if some of the resources have made heuristic decisions to commit
and others to rollback. This is a potential problematic scenario, where now the data most
probably is in an inconsistent state, where earlier two scenarios, the data would always be
consistent regardless it succeeded or not
○ This situation requires manual fixing of transactions by analyzing the Xids of each
transaction branch, and fixing them in target resource managers in question, e.g. database
servers (resource managers would keep a log of Xids when an Heuristic exception occurs)
When things go wrong -> Heuristic Exceptions!
16. How does he do it? Playing Transaction
Manager
● The first job of the transaction manager is to create Xids (javax.transaction.xa.Xid) for each
transaction branch
○ An Xid mainly contains the following information
■ gtrid - an identifier for the global transaction
■ bqual - an identifier for this specific transaction branch
● Extract XAResource objects for each resource of the resource managers, e.g. database
connections, JMS sessions
● Call XAResource#start() by parsing in the Xid created to represent that transaction branch
● Execute operations for resource that was started, e.g. executing SQL statements against a
database connection, removing a message from a message queue
● Call XAResource#end() by parsing in the same Xid which was used for starting it
● Call XAResource#prepare() by parsing in each ones respective Xids to execute the first phase of
2PC
● If everyone returns XAResource.XA_OK in prepare(), call XAResource#commit() for all the
participating XAResources in the global transaction
17. So… Should I Always Play Transaction
Manager?
● No!
● There are lot of behind the scenes complex operations done by the
transaction manager to handle all the operations such as persisting
transaction status and recovery
● It doesn’t make sense for an user application to handle this complex
logic
● Don’t try to solve a problem that is already solved by someone else
(and has most probably done a good job at it!)
19. Recommendations in Using XA
Transactions
● If you can avoid it, do avoid it! :)
● XA transactions are inherently expensive operations, because of the extra operations required
for the coordination of a global transaction. So for performance critical applications, this can be
a bottleneck
● Workarounds may be added in place of a distributed transaction, such as compensation actions
in the case of a inconsistent state at the end of a set of operations. This maybe considered if the
operations are not very sensitive to being in an inconsistent state for a short period
● The decision will depend on a balance between performance and how critical the
data/operations should be consistent at all times
● If things do go wrong in XA, it can actually go wrong really badly! .. as we have seen with
Heuristic exception scenario, it may be somewhat hard to recover from that, and also, recover
from physical failures may be impossible, e.g. the instance that has the transaction manager
binary logs are lost