Using modeshape with other JTA transaction
kiddinho Nov 13, 2014 9:20 PMHi all!
I have an application that using spring & modeshape, running in tomcat server. It's using jboss jta to manage jta transaction.
I want store data in my own database & also in modeshape store. But when my code use JTA transaction, it throws exception that:
javax.transaction.NotSupportedException: BaseTransaction.checkTransactionState - ARJUNA016051: thread is already associated with a transaction!
I'm using spring 3.1, modeshape 3.6.0Final, jboss jta 4.14.0
Here is my source code & cofiguration.
Thanks for helping
// source code
@Transactional(value = "XA_TRANSACTION", rollbackFor = {Exception.class})
public void doUpdate({
// Code insert data to my db
// Code insert data to modeshape
}
<bean id="jndiExporterForModeshape" class="mypackage.JndiExporter"> <property name="jndiMapping"> <map> <entry key="JNDIDatasource" value-ref="myXADatasource" /> </map> </property> </bean>
// spring datasource config
<bean id="myXADatasource" class="org.apache.commons.dbcp.managed.BasicManagedDataSource"
destroy-method="close">
<property name="transactionManager" ref="jbossTransactionManager" />
<property name="url" value="${database_com.url}" />
<property name="username" value="${database_com.username}" />
<property name="password" value="${database_com.password}" />
<property name="driverClassName" value="${database_com.driver}" />
<property name="maxActive" value="${database_xa.pool.max}" />
<property name="testWhileIdle" value="true" />
<property name="validationQuery" value="select 1" />
</bean>
// jta transaction config
<bean id="jbossTransactionManager" class="com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple"> </bean> <bean id="myJtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionManager" ref="jbossTransactionManager" /> <property name="defaultTimeout" value="500"></property> </bean> <tx:annotation-driven transaction-manager="myJtaTransactionManager" proxy-target-class="true" />
// repository config
{
"name" : "MYREPO",
"transactionMode" : "auto",
"monitoring" : {
"enabled" : true,
},
"workspaces" : {
"predefined" : ["DataStore", "FileStore", "Security"],
"default" : "DataStore",
"allowCreation" : true,
},
"storage" : {
"cacheName" : "repo",
"cacheConfiguration" : "repository/infinispan/cache-config.xml",
"transactionManagerLookup" = "mypackage.transaction.JbossTSStandaloneTransactionManagerLookup",
"binaryStorage" : {
"type" : "cache",
"dataCacheName" : "data",
"metadataCacheName" : "metadata",
"cacheConfiguration" : "repository/infinispan/store-config.xml",
"minimumBinarySizeInBytes" : 4096,
"description" : ""
}
},
"security" : {
"providers" : [
{
"name" : "Spring jcr Authentication Provider",
"classname" : "mypackage.security.provider.AppBasedSpringJcrAuthenticationProvider",
}
]
},
"query" : {
"enabled" : true,
"textExtracting": {
"threadPool" : "test",
"extractors" : {
"tikaExtractor":{
"name" : "General content-based extractor",
"classname" : "tika",
}
}
},
"indexStorage" : {
"type" : "filesystem",
"location" : "${modeshape_config_index_storage}",
"lockingStrategy" : "native",
"fileSystemAccessType" : "auto"
},
"indexing" : {
"threadPool" : "modeshape-workers",
"analyzer" : "org.apache.lucene.analysis.standard.StandardAnalyzer",
"similarity" : "org.apache.lucene.search.DefaultSimilarity",
"batchSize" : -1,
"indexFormat" : "LUCENE_35",
"readerStrategy" : "shared",
"mode" : "sync",
"asyncThreadPoolSize" : 1,
"asyncMaxQueueSize" : 50,
"backend" : {
"type" : "lucene",
},
"rebuildOnStartup" : {
"when" : "always",
"includeSystemContent" : true,
"mode" : "SYNC"
},
"hibernate.search.custom.overridden.property" : "value",
}
},
"sequencing" : {
"removeDerivedContentWithOriginal" : true,
"threadPool" : "modeshape-workers",
"sequencers" : {
"ZIP Sequencer" : {
"description" : "ZIP Files loaded under '/files' and extracted into '/sequenced/zip/$1'",
"classname" : "ZipSequencer",
"pathExpressions" : ["default:/files(//)(*.zip[*])/jcr:content[@jcr:data] => default:/sequenced/zip/$1"],
},
"Delimited Text File Sequencer" : {
"classname" : "org.modeshape.sequencer.text.DelimitedTextSequencer",
"pathExpressions" : [
"default:/files//(*.csv[*])/jcr:content[@jcr:data] => default:/sequenced/text/delimited/$1"
],
"splitPattern" : ","
}
}
},
"node-types" : [
]
}
// cache config
<namedCache name="repo"> <transaction transactionManagerLookupClass="mypackage.transaction.JbossTSStandaloneTransactionManagerLookup" transactionMode="TRANSACTIONAL" lockingMode="PESSIMISTIC"/> <loaders passivation="false" shared="false" preload="false"> <loader class="org.infinispan.loaders.jdbc.binary.JdbcBinaryCacheStore" fetchPersistentState="false" purgeOnStartup="false"> <properties> <property name="cacheName" value="repo"/> <property name="bucketTableNamePrefix" value="qmtb" /> <property name="idColumnName" value="ID"/> <property name="dataColumnName" value="DATA"/> <property name="timestampColumnName" value="TIMESTAMP"/> <property name="timestampColumnType" value="bigint"/> <property name="idColumnType" value="character varying(255)"/> <property name="dataColumnType" value="bytea"/> <property name="connectionFactoryClass" value="org.infinispan.loaders.jdbc.connectionfactory.ManagedConnectionFactory" /> <property name="datasourceJndiLocation" value="JNDIDatasource"/> </properties> </loader> </loaders> </namedCache>
// transaction manager lookup class
public class JbossTSStandaloneTransactionManagerLookup implements
TransactionManagerLookup {
private TransactionManager getTransactionManager(Properties props) throws HibernateException {
try {
//Call com.arjuna.ats.jta.TransactionManager.transactionManager
Class<?> jbossTransactionManagerClass = Class.forName( "com.arjuna.ats.jta.TransactionManager" );
final Method getTransactionManagerMethod = jbossTransactionManagerClass.getMethod( "transactionManager" );
//static method call
return (TransactionManager) getTransactionManagerMethod.invoke( null );
}
catch ( Exception e ) {
throw new HibernateException( "Could not obtain JBoss Transactions transaction manager instance", e );
}
}
@Override
public TransactionManager getTransactionManager() throws Exception {
return getTransactionManager(null);
}
}