| Author |
Message |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 10/04/2011 04:09:04
|
luddy
neo
Joined: 09/19/2011 03:28:59
Messages: 9
Offline
|
Hello, I am trying to configure XA transactions across a cache.XXX() and a CacheWriter write-through and am getting the following error.
Can anyone take a quick look and see what is amiss?
I am using:
product-name = Ehcache Core Enterprise
version = 2.5.0-SNAPSHOT
I am embedding ehcache inside my app.
Thank you.
Code:
net.sf.ehcache.transaction.TransactionException: JTA transaction not started
at net.sf.ehcache.transaction.xa.XATransactionStore.getCurrentTransaction(XATransactionStore.java:99)
at net.sf.ehcache.transaction.xa.XATransactionStore.getOrCreateXAResource(XATransactionStore.java:110)
at net.sf.ehcache.transaction.xa.XATransactionStore.getOrCreateTransactionContext(XATransactionStore.java:151)
at net.sf.ehcache.transaction.xa.XATransactionStore.putWithWriter(XATransactionStore.java:424)
at net.sf.ehcache.Cache.putInternal(Cache.java:1484)
at net.sf.ehcache.Cache.putWithWriter(Cache.java:1442)
at com.anz.mosa.tradematcher.cache.Test.testTransaction(Test.java:78)
at com.anz.mosa.tradematcher.cache.Test.main(Test.java:64)
2011-10-04 18:35:32,903 9687 [main] ERROR com.anz.mosa.tradematcher.cache.Test - Rolling back!!!!!!
The small test case just tries to enter two items into cache and then remove them. First time accessing cache fails because there is no transaction.
Code:
@SuppressWarnings("unchecked")
@Transactional
public void testTransaction(){
Cache testCache = getCacheManager().cacheManager.getCache( "TEST" );
try{
//cacheManager.getTransactionController().begin();
testCache.putWithWriter( new Element( "testkey1", "testvalue1" ) ); // <--------(Test.java:78)
testCache.putWithWriter( new Element( "testkey2", "testvalue2" ) );
//cacheManager.getTransactionController().commit();
} catch( CacheException e ){
//cacheManager.getTransactionController().rollback();
e.printStackTrace();
}
try{
//cacheManager.getTransactionController().begin();
testCache.removeWithWriter( "testkey1" );
testCache.removeWithWriter( "testkey2" );
//cacheManager.getTransactionController().commit();
} catch( CacheException ce ){
logger.error( "Rolling back!!!!!!");
//cacheManager.getTransactionController().rollback();
}
}
Here is my ehcache configuration:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<defaultCache
maxElementsInMemory="500"
eternal="true"
overflowToDisk="false"
memoryStoreEvictionPolicy="LFU">
</defaultCache>
<cache name="TEST" maxElementsInMemory="10" eternal="true"
overflowToDisk="true" memoryStoreEvictionPolicy="LFU" diskPersistent="true" transactionalMode="xa_strict">
<cacheWriter writeMode="write_through" >
<cacheWriterFactory
class="com.anz.mosa.tradematcher.cache.TestCacheWriterFactory"/>
</cacheWriter>
</cache>
</ehcache>
Here is my Spring configuration:
Code:
<bean id="dao" class="com.anz.mosa.tradematcher.dao.TestDaoJdbcImpl">
<property name="dataSource" ref="remoteDataSource" />
</bean>
<bean id="remoteDataSource" class="bitronix.tm.resource.jdbc.PoolingDataSource"
init-method="init" destroy-method="close">
<property name="className" value="${jdbc.driverClassName}" />
<property name="uniqueName" value="remoteAccountDataSource" />
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="15" />
<property name="allowLocalTransactions" value="true" />
<property name="driverProperties">
<props>
<prop key="user">user1</prop>
<prop key="password">abc123</prop>
<prop key="URL">${jdbc.url}</prop>
</props>
</property>
</bean>
<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" depends-on="transactionManager">
<property name="configLocation">
<value>classpath:ehcache-test.xml</value>
</property>
</bean>
<bean id="btmConfig" factory-method="getConfiguration"
class="bitronix.tm.TransactionManagerServices">
<property name="serverId" value="tradeMatcherServerId" />
<property name="logPart1Filename" value="/temp/btm1.tlog" />
<property name="logPart2Filename" value="/temp/btm2.tlog" />
<property name="warnAboutZeroResourceTransaction" value="false" />
<property name="gracefulShutdownInterval" value="0" />
</bean>
<bean id="bitronixTransactionManager" factory-method="getTransactionManager"
class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig"
destroy-method="shutdown" />
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="bitronixTransactionManager" />
<property name="userTransaction" ref="bitronixTransactionManager" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 10/05/2011 15:57:50
|
gkeim
ophanim
Joined: 12/05/2006 10:22:37
Messages: 685
Location: Terracotta, Inc.
Offline
|
Are there any errors/warnings in the Ehcache log?
Note that Bitronix 2.0.0 or later is required.
|
Gary Keim (terracotta developer) Want to post to this forum? Join the Terracotta Community |
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 10/06/2011 03:13:42
|
lorban
master
Joined: 01/08/2010 13:09:16
Messages: 98
Location: CET
Offline
|
The TransactionException: JTA transaction not started exception clearly states that you're trying to access a cache outside the context of a JTA transaction.
I noticed you marked your testTransaction() method with Spring's @Transactional annotation but apparently that had no effect for some reason.
I suggest you to review your spring config and to make sure it really starts a transaction before calling your method as the problem definitely seems to be in that area.
|
Ludovic Orban (Terracotta engineer) |
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 10/06/2011 23:41:30
|
eneset
neo
Joined: 10/06/2011 23:36:40
Messages: 2
Offline
|
lorban wrote:
The TransactionException: JTA transaction not started exception clearly states that you're trying to access a cache outside the context of a JTA transaction.
I noticed you marked your testTransaction() method with Spring's @Transactional annotation but apparently that had no effect for some reason.
I suggest you to review your spring config and to make sure it really starts a transaction before calling your method as the problem definitely seems to be in that area.
No, the problem definitely seems to be with Ehcache. When I use multiple XA enabled resources and start, say, with database or Active MQ connection then Ehcache joins the transaction, no worries. When Ehcache is the only(!) participant, that no luck, 'JTA Transaction Not Started' exception...
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 10/10/2011 00:29:41
|
lorban
master
Joined: 01/08/2010 13:09:16
Messages: 98
Location: CET
Offline
|
Are you running your app in an application server? It could be that Ehcache detected a different TM than the one you're willing to use.
You can check which one Ehcache is using by enabling debug logs on net.sf.ehcache.transaction.manager.DefaultTransactionManagerLookup and look for a log starting with 'Found TransactionManager for ' during startup.
You could also try directly instantiating DefaultTransactionManagerLookup and calling getTransactionManager() to figure out which one Ehcache has detected.
Ehcache clearly says that it cannot work on the cache because no transaction was started on the transaction manager it decided to use. That definitely means there is some mismatch between what you're observing and what's actually going on.
|
Ludovic Orban (Terracotta engineer) |
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 10/10/2011 01:14:01
|
eneset
neo
Joined: 10/06/2011 23:36:40
Messages: 2
Offline
|
No, I run it in Spring with both Bitronix and Atomikos.
Bitronix turned out to be a very poor TM. Only supports JDBC, JMS and Ehcache via special adapter. With Atomikos I was able to enlist custom XAResources and they were successfully processed.
The problem it, when you do PUT, Ecache enlists itself as a transaction participant. When you use, GET, it doesn't. To put in differently, Ecache is unable to trigger XA transaction. If another resource is present, like JDBC XA pool or JMS XA pool, they trigger the transaction.
The worst part is, if I want to read JMS queue and put the message in Ehcache in one XA transaction, it work. When I read, I don't really want to do any XA but Ehcache wants JTA transaction to be started and fails with the same exception.
I short, there's no way to do XA writes and non-transactional reads to the same cache.
|
|
|
 |
|
|