Use JTA global transactions to coordinate GemFire cache transactions and JDBC transactions.
Using JTA, your application controls all transactions in the same standard way, whether the transactions act on the GemFire cache, a JDBC resource, or both together. When a JTA global transaction is done, the GemFire transaction and the database transaction are both complete.
An application creates a global transaction by using javax.transaction.UserTransaction bound to the JNDI context java:/UserTransaction to start and terminate transactions. During the transaction, cache operations are done through GemFire as usual as described in GemFire Cache Transactions.
GemFire can work with the JTA transaction managers of several containers like JBoss, WebLogic, GlassFish, and so on.
At startup GemFire looks for a TransactionManager (javax.transaction.TransactionManager) that has been bound to its JNDI context. When GemFire finds such an external transaction manager, all GemFire region operations (such as get and put) will participate in global transactions hosted by this external JTA transaction manager.
This figure shows the high-level operation of a JTA global transaction whose resources include a GemFire cache and a database.
You can disable JTA in any region that should not participate in JTA transactions. See Turning Off JTA Transactions.
Use the following procedure to run a GemFire global JTA transaction coordinated by an external JTA transaction manager.
You can also use GemFire as the JTA transaction manager.
GemFire ships with its own implementation of a JTA transaction manager. However, note that this implementation is not XA-compliant; therefore, it does not persist any state, which could lead to an inconsistent state after recovering a crashed member.
The GemFire JTA transaction manager is initialized when the GemFire cache is initialized. Until then, JTA is not available for use. The application starts a JTA transaction by using the UserTransaction.begin method. The UserTransaction object is the application’s handle to instruct the JTA transaction manager on what to do.
The GemFire JTA implementation also supports the J2EE Connector Architecture (JCA) ManagedConnectionFactory.
This topic describes how to run a JTA global transaction in GemFire.
To run a global transaction, perform the following steps:
Context ctx = cache.getJNDIContext();
This returns javax.naming.Context and gives you the JNDI associated with the cache. The context contains the TransactionManager, UserTransaction, and any configured JDBC resource manager.
UserTransaction txManager = (UserTransaction)ctx.lookup("java:/UserTransaction");With UserTransaction, you can begin, commit, and rollback transactions.
If a global transaction exists, when you use the cache, it automatically joins the transaction. Operations on a region automatically detect and become associated with the existing global transaction through JTA synchronization. If the global transaction has been marked for rollback, however, the GemFire cache is not allowed to enlist with that transaction. Any cache operation that causes an attempt to enlist throws a FailedSynchronizationException.
The GemFire cache transaction’s commit or rollback is triggered when the global transaction commits or rolls back. When the global transaction is committed using the UserTransaction interface, the transactions of any registered JTA resources are committed, including the GemFire cache transaction. If the cache or database transaction fails to commit, UserTransaction throws a TransactionRolledBackException. If a commit or rollback is attempted directly on a GemFire transaction that is registered with JTA, that action throws an IllegalStateException.