BigMemory 4.4.0 | Product Documentation | BigMemory Max Configuration Guide | Working with Transactions | Strict XA (Support for All JTA Components)
 
Strict XA (Support for All JTA Components)
Note that Ehcache as an XA resource:
*Has an isolation level of ReadCommitted.
*Updates the underlying store asynchronously, potentially creating update conflicts. With this optimistic locking approach, Ehcache might force the transaction manager to roll back the entire transaction if a commit() generates a RollbackException (indicating a conflict).
*Can work alongside other resources such as JDBC or JMS resources.
*Guarantees that its data is always synchronized with other XA resources.
*Can be configured on a per-cache basis (transactional and non-transactional caches can exist in the same configuration).
*Automatically performs enlistment.
*Can be used standalone or integrated with frameworks such as Hibernate.
*Is tested with the most common transaction managers by Atomikos, Bitronix, JBoss, WebLogic, and others.
Configuration
To configure a cache as an XA resource able to participate in JTA transactions, the following <cache> attributes must be set as shown:
*transactionalMode="xa_strict"
*copyOnRead="true"
*copyOnWrite="true"
In addition, the <cache> sub-element <terracotta> must not have clustering disabled.
For example, the following cache is configured for JTA transactions with strict XA:
<cache name="com.my.package.Foo"
maxEntriesLocalHeap="500"
eternal="false"
copyOnRead="true"
copyOnWrite="true"
consistency="strong"
transactionalMode="xa_strict">
<persistence strategy="distributed"/>
<terracotta />
</cache>
Any other XA resource that could be involved in the transaction, such as a database, must also be configured to be XA compliant.
Usage
Your application can directly use a transactional cache in transactions. This usage must occur after the transaction manager has been set to start a new transaction and before it has ended the transaction.
For example:
...
myTransactionMan.begin();
Cache fooCache = cacheManager.getCache("Foo");
fooCache.put("1", "Bar");
myTransactionMan.commit();
...
If more than one transaction writes to a cache, it is possible for an XA transaction to fail. See Avoiding XA Commit Failures With Atomic Methods.
Setting Up Transactional Caches in Hibernate {#45557}
If your application is using JTA, you can set up transactional caches in a second-level cache with Ehcache for Hibernate. To do so, ensure the following:
Ehcache
*You are using Ehcache 2.1.0 or higher.
*The attribute transactionalMode is set to "xa" or "xa-strict".
*The cache is clustered (the <cache> element has the sub-element <terracotta clustered="true">). For example, the following cache is configured to be transactional:
<cache name="com.my.package.Foo"
...
transactionalMode="xa"> <terracotta /> </cache>
*The cache UpdateTimestampsCache is not configured to be transactional. Hibernate updates to org.hibernate.cache.UpdateTimestampsCache prevent it from being able to participate in XA transactions.
Hibernate
*You are using Hibernate 3.3.
*The factory class used for the second-level cache is net.sf.ehcache.hibernate.EhCacheRegionFactory.
*Query cache is turned off.
*The value of current_session_context_class is jta.
*The value of transaction.manager_lookup_class is the name of a TransactionManagerLookup class (see your Transaction Manager).
*The value of transaction.factory_class is the name of a TransactionFactory class to use with the Hibernate Transaction API.
*The cache concurrency strategy is set to TRANSACTIONAL. For example, to set the cache concurrency strategy for com.my.package.Foo in hibernate.cfg.xml:
<class-cache class="com.my.package.Foo" usage="transactional"/>
Or in a Hibernate mapping file (hbm file):
<cache usage="transactional"/>
Or using annotations:
@Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)
public class Foo {...}
Important:
WARNING: Use the TRANSACTIONAL concurrency strategy with transactional caches only. Using with other types of caches will cause errors.