Configuring it with XML
You can create a XML file to configure a CacheManager, lookup a specific transaction manager and configure XA caches:
<service>
<tx:jta-tm transaction-manager-lookup-class=
"org.ehcache.transactions.xa.txmgr.btm.BitronixTransactionManagerLookup"/>
<!-- 1 -->
</service>
<cache alias="xaCache"> <!-- 2 -->
<key-type>java.lang.String</key-type>
<value-type>java.lang.String</value-type>
<heap unit="entries">20</heap>
<tx:xa-store unique-XAResource-id="xaCache" /> <!-- 3 -->
</cache>
1 | Declare a TransactionManagerLookup that will lookup your transaction manager. |
2 | Configure a xaCache cache the normal way. |
3 | Configure xaCache as an XA cache, giving it xaCache as its unique XAResource ID. |
In order to parse an XML configuration, you can use the XmlConfiguration type:
BitronixTransactionManager transactionManager =
TransactionManagerServices.getTransactionManager(); // 1
URL myUrl = this.getClass().getResource("/docs/configs/xa-getting-started.xml");
// 2
Configuration xmlConfig = new XmlConfiguration(myUrl); // 3
CacheManager myCacheManager = CacheManagerBuilder.newCacheManager(xmlConfig);
// 4
myCacheManager.init();
myCacheManager.close();
transactionManager.shutdown();
1 | The Bitronix transaction manager must be started before the cache manager is initialized. |
2 | Create a URL to your XML file's location. |
3 | Instantiate a XmlConfiguration passing it the XML file's URL. |
4 | Using the staticorg.ehcache.config.builders.CacheManagerBuilder.newCacheManager ( org.ehcache.config.Configuration ) lets you create your CacheManager instance using the Configuration from the XmlConfiguration. |
And here is what the BitronixTransactionManagerLookup implementation looks like:
public class BitronixTransactionManagerLookup
implements TransactionManagerLookup { // 1
private static final Logger LOGGER = LoggerFactory.getLogger(
BitronixTransactionManagerLookup.class);
@Override
public TransactionManagerWrapper lookupTransactionManagerWrapper() { // 2
if (!TransactionManagerServices.isTransactionManagerRunning()) { // 3
throw new IllegalStateException("BTM must be started beforehand");
}
TransactionManagerWrapper tmWrapper = new TransactionManagerWrapper(
TransactionManagerServices.getTransactionManager(),
new BitronixXAResourceRegistry()); // 4
LOGGER.info("Using looked up transaction manager : {}", tmWrapper);
return tmWrapper;
}
}
1 | The TransactionManagerLookup interface must be implemented and the offer a no-arg constructor. |
2 | The lookupTransactionManagerWrapper() method must return a TransactionManagerWrapper instance. |
3 | Here is the check that makes sure BTM is started. |
4 | The TransactionManagerWrapper class is constructed with both the javax.transaction.TransactionManager instance as well as a XAResourceRegistryinstance. The latter is used to register the javax.transaction.xa.XAResource instances of the cache with the transaction manager using an implementation-specific mechanism. If your JTA implementation doesn't require that, you can use the NullXAResourceRegistryinstead. |