由于数据同步需要,在两个oracle 数据库之间进行数据同步,其中有些业务需要分布式事务处理。前段时间也折腾了好久才弄完,贴出来给大家参考一下。
开始在网上搜索相关资料,都说Tomcat不支持分布式事务,只能使用Atomikos 和J0TM,JOTM貌似现在已经不更新了,只能使用Atomikos ,而且分布式事务只能使用JTA事务,我也姑且这么认为吧,暂时就不去考究了。下面是spring 和Atomikos的详细使用:
1、准备包:
atomikos-util-4.0.4.jar
transactions-4.0.4.jar
transactions-api-4.0.4.jar
transactions-jdbc-4.0.4.jar
transactions-jta-4.0.4.jar
2、配置数据源:
3、事务配置
下面是mybatis 配置使用数据源和事务
最后记得给用户权限:
测试很简单,写一个方法同时对两个数据库进行DML操作,然后手动抛出异常,看看是否同时成功或失败。
以上配置亲测完全没问题。配置过程中的错误基本上是指定的class不对,或者包冲突导致,踩了不少坑。虽然对配置种的某些项还不是很了解,但是先用着吧,任务排第一位
,后续有空再慢慢研究!
开始在网上搜索相关资料,都说Tomcat不支持分布式事务,只能使用Atomikos 和J0TM,JOTM貌似现在已经不更新了,只能使用Atomikos ,而且分布式事务只能使用JTA事务,我也姑且这么认为吧,暂时就不去考究了。下面是spring 和Atomikos的详细使用:
1、准备包:
atomikos-util-4.0.4.jar
transactions-4.0.4.jar
transactions-api-4.0.4.jar
transactions-jdbc-4.0.4.jar
transactions-jta-4.0.4.jar
2、配置数据源:
点击(此处)折叠或打开
- <bean id="cocdataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
- <property name="uniqueResourceName" value="cocdataSource"/>
-
- <property name="xaDataSourceClassName" value="oracle.jdbc.xa.client.OracleXADataSource"/>
- <property name="xaProperties">
- <props>
- <prop key="URL">${coc.url}</prop>
- <prop key="user">${coc.username}</prop>
- <prop key="password">${coc.password}</prop>
- </props>
- </property>
- <property name="minPoolSize" value="${minPoolSize}" />
- <property name="maxPoolSize" value="${maxPoolSize}" />
- <property name="borrowConnectionTimeout" value="${borrowConnectionTimeout}" />
- <property name="testQuery" value="${testQuery}" />
- <property name="maintenanceInterval" value="${maintenanceInterval}" />
- </bean>
-
- <bean id="subprjdataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
- <property name="uniqueResourceName" value="subprjdataSource"/>
- <property name="xaDataSourceClassName" value="oracle.jdbc.xa.client.OracleXADataSource"/>
- <property name="xaProperties">
- <props>
- <prop key="URL">${subprj15.url}</prop>
- <prop key="user">${subprj15.username}</prop>
- <prop key="password">${subprj15.password}</prop>
- </props>
- </property>
- <property name="minPoolSize" value="${minPoolSize}" />
- <property name="maxPoolSize" value="${maxPoolSize}" />
- <property name="borrowConnectionTimeout" value="${borrowConnectionTimeout}" />
- <property name="testQuery" value="${testQuery}" />
- <property name="maintenanceInterval" value="${maintenanceInterval}" />
- </bean>
3、事务配置
点击(此处)折叠或打开
- <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
- init-method="init" destroy-method="close">
- <property name="forceShutdown">
- <value>true</value>
- </property>
- </bean>
- <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
- <!-- 事务超时时间 -->
- <property name="transactionTimeout" value="100000" />
- </bean>
-
- <!-- 配置jta事务管理 -->
- <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
- <property name="transactionManager" ref="atomikosTransactionManager" />
- <property name="userTransaction" ref="atomikosUserTransaction" />
- <property name="allowCustomIsolationLevels" value="true"/>
- </bean>
-
- <tx:advice id="txAdvice" transaction-manager="transactionManager">
- <tx:attributes>
- <tx:method name="delete*" propagation="REQUIRED" read-only="false"
- rollback-for="java.lang.Exception"/>
- <tx:method name="insert*" propagation="REQUIRED" read-only="false"
- rollback-for="java.lang.Exception" />
- <tx:method name="update*" propagation="REQUIRED" read-only="false"
- rollback-for="java.lang.Exception" />
- <tx:method name="save*" propagation="REQUIRED" read-only="false"
- rollback-for="java.lang.Exception" />
- <tx:method name="add*" propagation="REQUIRED" read-only="false"
- rollback-for="java.lang.Exception" />
- <tx:method name="*_tx" propagation="REQUIRED" read-only="false"
- rollback-for="java.lang.Exception" />
- </tx:attributes>
- </tx:advice>
-
- <aop:aspectj-autoproxy proxy-target-class="true"/>
-
- <aop:config>
- <aop:pointcut id="pc" expression="execution(* com.coc.service..*(..)) or execution(* com.coc.task..*(..))" />
- <aop:advisor pointcut-ref="pc" advice-ref="txAdvice" />
- </aop:config>
-
-
- <tx:annotation-driven transaction-manager="transactionManager"/>
点击(此处)折叠或打开
- <!-- 配置mybatis -->
- <bean id="cocsqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
- <property name="dataSource" ref="cocdataSource" />
- <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"></property>
- </bean>
-
- <bean id="subprjsqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
- <property name="dataSource" ref="subprjdataSource" />
- <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"></property>
- </bean>
-
-
- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
- <property name="basePackage" value="com.coc.dao.coc"/>
- <property name="sqlSessionFactoryBeanName" value="cocsqlSessionFactory"/>
-
- </bean>
-
- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
- <property name="basePackage" value="com.coc.dao.subprj"/>
- <property name="sqlSessionFactoryBeanName" value="subprjsqlSessionFactory"/>
- </bean>
点击(此处)折叠或打开
- grant select on sys.dba_pending_transactions to xxxx
- grant select on sys.pending_trans$ to xxxx;
- grant select on sys.dba_2pc_pending to xxxx;
- grant execute on sys.dbms_system to xxxx;
-
- grant select on sys.dba_pending_transactions to zzzz
- grant select on sys.pending_trans$ to zzzz;
- grant select on sys.dba_2pc_pending to zzzz;
- grant execute on sys.dbms_system to zzzz
测试很简单,写一个方法同时对两个数据库进行DML操作,然后手动抛出异常,看看是否同时成功或失败。
以上配置亲测完全没问题。配置过程中的错误基本上是指定的class不对,或者包冲突导致,踩了不少坑。虽然对配置种的某些项还不是很了解,但是先用着吧,任务排第一位
![](http://blog.itpub.net/kindeditor/plugins/emoticons/images/13.gif)
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30741760/viewspace-2126511/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/30741760/viewspace-2126511/