Java Distributed Transactions

22
Distributed Transactions with Java Anjana Fernando Senior Technical Lead WSO2 Inc.

Transcript of Java Distributed Transactions

Page 1: Java Distributed Transactions

Distributed Transactions with Java

Anjana FernandoSenior Technical Lead

WSO2 Inc.

Page 2: Java Distributed Transactions

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

Page 3: Java Distributed Transactions

What is a Distributed Transaction?

Page 4: Java Distributed Transactions

Why do we need it?

Page 5: Java Distributed Transactions

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

Page 6: Java Distributed Transactions

XA Distributed Transaction Model

Source: http://www.javaworld.com/article/2077714/java-web-development/xa-transactions-using-spring.html

Page 7: Java Distributed Transactions

Two Phase Commit (2PC) Protocol

Page 8: Java Distributed Transactions

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

Page 9: Java Distributed Transactions

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

Page 10: Java Distributed Transactions

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

Page 11: Java Distributed Transactions

Flow of a Distributed Transaction try {

txManager.begin();

msg = XASession -> removeMessage

conn1 = XADataSource -> getConnection doDataOperation1(msg, conn1);

conn2 = XADataSource -> getConnection doDataOperation2(msg, conn2);

txManager.commit();

} catch (SomeException e) {

txManager.rollback();

}

Page 12: Java Distributed Transactions

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

Page 13: Java Distributed Transactions

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

Page 14: Java Distributed Transactions

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

Page 15: Java Distributed Transactions

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

Page 16: Java Distributed Transactions

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!

Page 17: Java Distributed Transactions

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

Page 18: Java Distributed Transactions

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!)

Page 19: Java Distributed Transactions

Demo

Page 20: Java Distributed Transactions

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

Page 21: Java Distributed Transactions

Questions?

Page 22: Java Distributed Transactions

Thank You!