Usage of the JBoss Cache BatchModeTransactionManager
Discussion of the purpose, limitations and proper utilization of the JBoss Cache BatchModeTransactionManager class.
In general, use of BatchModeTransactionManager is not encouraged, and should only be done by those very familiar with how JBoss Cache uses transactions.
One of the nicest features of JBoss Cache is it's ability to let you use a JTA Transaction to scope or "batch" a series of operations on the cache. If your cache is properly configured with a TransactionManagerLookup, the JTA TransactionManager in your environment can be found, and using it JBC will detect the existence of an ongoing transaction and integrate its operations with the transaction. From this you get all sorts of nice behavior, including:
Changes you make to the cache are automatically rolled back if the transaction rolls back.
Locks you acquire during an invocation are held until the transaction commits or rolls back.
Changes are all replicated around the cluster in a batch as part of the transaction commit process. Reduces replication chatter if multiple changes occur during the transaction.
If synchronous replication or invalidation are used, a failure in replication/invalidation will cause the transaction to roll back.
If a CacheLoader is used, and that cache loader works with a JTA resource (e.g. a JTA DataSource), the JTA resource can also participate in the transaction.
This is all great, but there are uses cases where it's nice to have many of these benefits without the involvement of a JTA Transaction. An example of this is FIELD granularity web session replication in JBoss AS. The session replication layer wants to batch changes made to session objects during the course of the request, but having the session replication code start a JTA Transaction at the start of the request is not a viable solution. What if the user code needs to start and commit a transaction as part of request processing? There is no clean way to separate the requirements of the user code from those of the session replication layer, if they are both using the same JTA TransactionManager.
A long term solution to this problem is discussed at http://jira.jboss.com/jira/browse/JBCACHE-991. A current workaround is configuring org.jboss.cache.transaction.BatchModeTransactionManagerLookup as the TransactionManagerLookup. The class will create an instance of org.jboss.cache.transaction.BatchModeTransactionManager and provide it to the cache.
BatchModeTransactionManagerLookup does not bind anything into JNDI. So, it will not be possible to retrieve via a JNDI lookup the BatchModeTransactionManager it creates. A reference to the BatchModeTransactionManager can only be obtained by invoking the getTransactionManager() method on the cache.
Once a reference to the transaction manager is obtained, it can be used via the normal javax.transaction.TransactionManager API.
Limitations of the BatchModeTransactionManager
The problem with BatchModeTransactionManager is it implements the JTA TransactionManager interface, and thus can fool users into thinking of it as a true, full featured JTA TransactionManager. It most decidedly is not! It's historical roots are in a mock transaction manager implementation used for unit testing JBoss Cache. No attempt whatsoever has been made to provide all the features of a JTA transaction manager or to test its compliance with the JTA specifications. Where it has been tested is in providing the proper handling for basic operations needed by JBoss Cache, e.g. associating a Transaction object with a thread and properly invoking the javax.transaction.Synchronization callbacks when the transaction is committed or rolled back.
A key point to understand is that no attempt should be made to associate a JTA resource with a Transaction started by BatchModeTransactionManager. The most likely way this sort of misuse could happen is by attempting to use a CacheLoader (e.g. JDBCCacheLoader) that is configured to work with a JTA DataSource.
In general, use of BatchModeTransactionManager is not encouraged, and should only be done by those very familiar with how JBoss Cache uses transactions. And, of course, thorough testing is a must.