Atomikos Forum |
|
Hi,
I am developing an application using Spring and Eclipselink. We have a requirement to support XA transactions since there would be transactions spanning over multiple DB datasources in our application. I am trying to use atomikos as the JTA implementation along with Spring JTA support. I am able to query the datasource data however I am not able to commit the data to the database. There is no exception thrown by spring or atomikos during the transaction however the data is not getting committed to the database as well. My spring configuration goes as below. <bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" destroy-method="shutdown"> <property name="xaDataSourceClassName"> <value>oracle.jdbc.xa.client.OracleXADataSource</value></property> <property name="uniqueResourceName"><value>AGLTDB</value></property> <property name="xaProperties"> <props> <prop key="serverName">localhost</prop> <prop key="portNumber">1521</prop> <prop key="databaseName">xe</prop> <prop key="user">aglite</prop> <prop key="password">aglite</prop> <prop key="driverType">4</prop> <prop key="URL">jdbc:oracle:thin:@localhost:1521:xe</prop> </props> </property> </bean> <bean id="dataSourcePQ" class="com.atomikos.jdbc.AtomikosDataSourceBean" destroy-method="shutdown"> <property name="xaDataSourceClassName"><value>oracle.jdbc.xa.client.OracleXADataSource</value></property> <property name="uniqueResourceName"><value>PQDB</value></property> <property name="xaProperties"> <props> <prop key="serverName">localhost</prop> <prop key="portNumber">1521</prop> <prop key="databaseName">xe</prop> <prop key="user">aglite</prop> <prop key="password">aglite</prop> <prop key="driverType">4</prop> <prop key="URL">jdbc:oracle:thin:@localhost:1521:xe</prop> </props> </property> </bean> <bean id="pqPostProcessor" class="com.arisglobal.aglite.transaction.JtaPersistenceUnitPostProcessor"> <property name="jtaDataSource" ref="dataSourcePQ" /> </bean> <bean id="aglitePostProcessor" class="com.arisglobal.aglite.transaction.JtaPersistenceUnitPostProcessor"> <property name="jtaDataSource" ref="dataSource" /> </bean> <bean id="entityManagerFactory" class="com.xxx.EntityManagerFactoryBean"> <property name="jpaProvider" value="eclipselink" /> <property name="persistenceUnitName" value="XXX_DS" /> <property name="persistenceXmlLocation" value="classpath:META-INF/persistence-xxx.xml" /> <property name="dataSource" ref="dataSource" /> <property name="jpaVendorAdapter" ref="jpaVendorAdapter" /> <property name="persistenceUnitPostProcessors" ref="aglitePostProcessor" /> </bean> <bean id="entityManagerFactoryPQ" class="com.xxx.EntityManagerFactoryBean"> <property name="persistenceUnitName" value="xxxPQ" /> <property name="persistenceXmlLocation" value="classpath:META-INF/persistence-yyy.xml" /> <property name="dataSource" ref="dataSourcePQ" /> <property name="jpaVendorAdapter" ref="jpaVendorAdapter" /> <property name="persistenceUnitPostProcessors" ref="pqPostProcessor" /> </bean> <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close"> <property name="forceShutdown" value="false" /> </bean> <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"> <property name="transactionTimeout" value="300" /> </bean> <bean id="transactionManager" class="com.arisglobal.aglite.transaction.AGJtaTransactionManager"> <property name="transactionManager" ref="atomikosTransactionManager" /> <property name="userTransaction" ref="atomikosUserTransaction" /> </bean> I have also specified the transaction-type attribute for the persistence unit definitions as JTA. Could somebody please point me to solve this issue? Thanks in advance, Shashi
Hi,
Here is how we configured eclipselink to be aware of jta transaction manager. 1) eclipselink session customizer class @Configurable public class TransactionSessionCustomizer implements SessionCustomizer { private JtaTransactionManager jtaTransactionManager; public void setTransactionManager( JtaTransactionManager jtaTransactionManager) { this.jtaTransactionManager = jtaTransactionManager; } public void customize(Session session) throws Exception { session .setExternalTransactionController(new CustomJTATransactionController()); } class CustomJTATransactionController extends JTATransactionController { @Override protected TransactionManager acquireTransactionManager() throws Exception { return jtaTransactionManager.getTransactionManager(); } } } 2) spring configuration for injected JtaTransactionManager <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionManager" ref="AtomikosTxMgr" /> <property name="userTransaction" ref="AtomikosUsrTx" /> <property name="transactionSynchronizationName" value="SYNCHRONIZATION_ON_ACTUAL_TRANSACTION" /> <property name="allowCustomIsolationLevels" value="true" /> </bean> 3) set eclipselink.session.customizer property for entity manager factory <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> ... <property name="jpaProperties"> <props> ... <prop key="eclipselink.session.customizer"> com.s4hc.bes.dao.eclipselink.TransactionSessionCustomizer</prop> </props> </property> </bean> Note that we use AspectJ for weaving, and therefore JtaTransactionManager is injected in all TransactionSessionCustomizer instances on their creation (use of Configurable annotation). If you do not use AspectJ, some other way is needed to explicitly look up JtaTransactionManager from application context. HTH, Misa |