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.