目前开发的J2EE系统用到了两个数据源,需要分布式事物(JTA)的支持,但是tomcat不支持JTA,开发调试不太方便,本文通过使用atomikos实现了分布式事务的支持,理论可以运行在任何java容器中。
一、将以下jar包放到lib目录下
二、将配置文件jta.properties放到WEB-INF目录下,内容如下:
三、修改spring配置文件,建立2个数据源:
<bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close"> <description>oracle xa datasource</description> <property name="uniqueResourceName"> <value>oracle_ds</value> </property> <property name="xaDataSourceClassName"> <value>${jdbc.XADriverClassName}</value> </property> <property name="xaProperties"> <props> <prop key="user">${jdbc.username}</prop> <prop key="password">${jdbc.password}</prop> <prop key="URL">${jdbc.url}</prop> </props> </property> <property name="minPoolSize" value="5" /> <property name="maxPoolSize" value="100" /> <property name="borrowConnectionTimeout" value="30" /> <property name="testQuery" value="select 1 from dual " /> <property name="maintenanceInterval" value="60" /> </bean> <bean id="dataSourceForAdmin" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close"> <description>oracle xa datasource</description> <property name="uniqueResourceName"> <value>oracle_ds_admin</value> </property> <property name="xaDataSourceClassName"> <value>${admin.jdbc.XADriverClassName}</value> </property> <property name="xaProperties"> <props> <prop key="user">${admin.jdbc.username}</prop> <prop key="password">${admin.jdbc.password}</prop> <prop key="URL">${admin.jdbc.url}</prop> </props> </property> <property name="minPoolSize" value="5" /> <property name="maxPoolSize" value="100" /> <property name="borrowConnectionTimeout" value="30" /> <property name="testQuery" value="select 1 from dual" /> <property name="maintenanceInterval" value="60" /> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">false</prop> <prop key="hibernate.current_session_context_class">jta</prop> <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop> </props> </property> <property name="packagesToScan" value="com.domain"/> </bean> <bean id="sessionFactoryForAdmin" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSourceForAdmin" /> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">false</prop> <prop key="hibernate.current_session_context_class">jta</prop> <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop> </props> </property> <property name="packagesToScan" value="com.domain"/> </bean> <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close"> <description>UserTransactionManager</description> <property name="forceShutdown"> <value>true</value> </property> </bean> <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"> <property name="transactionTimeout" value="300" /> </bean> <bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionManager"> <ref bean="atomikosTransactionManager" /> </property> <property name="userTransaction"> <ref bean="atomikosUserTransaction" /> </property> </bean> <!-- 配置事务切面 --> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="get*" propagation="REQUIRED" read-only="true"/> <tx:method name="find*" propagation="REQUIRED" read-only="true"/> <tx:method name="query*" propagation="REQUIRED" read-only="true"/> <tx:method name="select*" propagation="REQUIRED" read-only="true"/> <tx:method name="save*" propagation="REQUIRED"/> <tx:method name="add*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="del*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="execute*" propagation="REQUIRED"/> <tx:method name="exec*" propagation="REQUIRED"/> <tx:method name="*" propagation="REQUIRED" read-only="true"/> </tx:attributes> </tx:advice> |
这里使用的是oracle10g,需要使用支持XA数据源的驱动,这里为 ojdbc14.jar 或者ojdbc6.jar 均可;
配置如下,注意和单数据源驱动类名称区别
五、dao和不同sessionfactory关联:
<bean id="answerQueryDao" class="com.dao.impl.AnswerQueryDaoImpl" scope="singleton"> <property name="sessionFactory"> <ref bean="sessionFactory"/> </property> </bean> <bean id="adminLoginTokenDao" class="com.dao.impl.AdminLoginTokenDaoImpl" scope="singleton"> <property name="sessionFactory"> <ref bean="sessionFactoryForAdmin"/> </property> </bean> |
六、只能使用openSession来获取session,不能通过getCurrentSession获取,并且要调用flush方法才能使增加删除修改操作生效如下:
七、测试成功,供需要的同行参考一下,不妥之处,还请网友拍砖。
struts2+spring3.2.9+hibernate4.2.0+atomikos3.8实现分布式事务JTA
原文:http://blog.csdn.net/super_scan/article/details/39474947