首页 > 其他 > 详细

JTA分布式事务实践

时间:2016-04-30 02:16:45      阅读:357      评论:0      收藏:0      [点我收藏+]

最近一直在研究怎么实现分布式事务,花了不少时间,测试工程启停测试了无数次,最终实现的时候其实也就是写一些配置文件,对于工程代码没什么影响。目前研究还不是很深入,对于全面崩溃恢复如何实现和测试还不清楚。本文先介绍基础的实现。

?

当业务需要在一个事务中操作多个不同的资源,例如多个数据库,消息队列,缓存等,那么就需要使用分布式事务了。在java中一般建议使用JTA,这样开发人员就不用关心什么叫XA协议,什么是两阶段提交协议。要使用JTA需要容器的支持,例如使用JBOSS,WebSphere;或者使用第三方组件例如JOTMAtomikos

?

JBOSS AS现在改名叫Wildfly了,以便和JBOSS EAP区分,后文我也改叫WildflyJOTM看起来是个死项目,我不打算使用。

?

由于目前开发框架基于Spring+JPA设计,所以本文的配置主要是在spring中。其实用EJB的话配置更简单,但需要容器支持。

?

一、Wildfly中配置JTA

1、配置数据库驱动(oracle

a)???????? 首先按照以下路径新增目录:

wildfly-9.0.0.CR1\modules\system\layers\base\com\oracle\ojdbc14\main

b)???????? 把驱动文件ojdbc14.jar复制到此目录下

c)???????? main目录下新增配置文件module.xml

mudule.xml

<?xml version="1.0" encoding="UTF-8"?>

<module xmlns="urn:jboss:module:1.1" name="com.oracle.ojdbc14">

??? <resources>

??????? <resource-root path="ojdbc14.jar"/>

??? </resources>

??? <dependencies>

??????? <module name="javax.api"/>

??????? <module name="javax.transaction.api"/>

??? </dependencies>

</module>

?

打开wildflystandalone.xml配置文件(使用standalone模式启动,domain模式还没尝试),找到<subsystem xmlns="urn:jboss:domain:datasources:3.0">配置项目,在<drivers>里增加oracle驱动

增加

<driver name="oracle" module="com.oracle.ojdbc14">

??? <driver-class>oracle.jdbc.OracleDriver</driver-class>

??? <xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>

</driver>

?

2、配置XA数据源

配置两个xa的数据源,暂时都是数据库,以后学会JMS后再加上。

?

配置 1.2.1 ?oracle数据源-intf

<xa-datasource jndi-name="java:jboss/datasources/intfDS" pool-name="intf" enabled="true" use-ccm="false">

<xa-datasource-property name="URL">

??????? jdbc:oracle:thin:@127.0.0.1:1521:orcl

</xa-datasource-property>

??? <driver>oracle</driver>

??? <xa-pool>

??????? <is-same-rm-override>false</is-same-rm-override>

??????? <interleaving>false</interleaving>

??????? <pad-xid>false</pad-xid>

??????? <wrap-xa-resource>true</wrap-xa-resource>

??? </xa-pool>

??? <security>

??????? <user-name>intf</user-name>

??????? <password>intf</password>

??? </security>

??? <validation>

??? ????<validate-on-match>false</validate-on-match>

??? ????<background-validation>false</background-validation>

?????????? <background-validation-millis>0</background-validation-millis>

??? </validation>

??? <statement>

??????? <prepared-statement-cache-size>0</prepared-statement-cache-size>

????? ??<share-prepared-statements>false</share-prepared-statements>

</statement>

</xa-datasource>

?

配置 2.2 ?oracle数据源-cx

<xa-datasource jndi-name="java:jboss/datasources/cxDS" pool-name="cx" enabled="true" use-ccm="false">

??? <xa-datasource-property name="URL">

??????? jdbc:oracle:thin:@127.0.0.1:1521:orcl

??? </xa-datasource-property>

??? <driver>oracle</driver>

??? <xa-pool>

?? ?????<is-same-rm-override>false</is-same-rm-override>

???? ???<interleaving>false</interleaving>

???? ???<pad-xid>false</pad-xid>

???? ???<wrap-xa-resource>true</wrap-xa-resource>

?? ?</xa-pool>

? ??<security>

?? ?????<user-name>congxing</user-name>

?? ?????<password>congxing</password>

??? </security>

? ??<recovery>

??????? <recover-credential>

????????? ??<user-name>congxing</user-name>

????????? ??<password>congxing</password>

??????? </recover-credential>

?? ?</recovery>

?? ?<validation>

?? ?????<validate-on-match>false</validate-on-match>

?? ?????<background-validation>false</background-validation>

???? ???<background-validation-millis>0</background-validation-millis>

?? ?</validation>

? ??<statement>

?????? ?<prepared-statement-cache-size>0</prepared-statement-cache-size>

????? ??<share-prepared-statements>false</share-prepared-statements>

??? </statement>

</xa-datasource>

?

3、配置JPA-persistence.xml

配置两个persistence-unit,分别使用上面的数据源

?

配置 1.3.1 ? intf持久化单元

<persistence-unit name="intf" transaction-type="JTA">

?? <jta-data-source>java:jboss/datasources/intfDS</jta-data-source>

</persistence-unit>

?

配置 1.3.2 ?cx持久化单元

<persistence-unit name="cx" transaction-type="JTA">

?? <jta-data-source>java:jboss/datasources/cxDS</jta-data-source>

</persistence-unit>

?

4、配置EntityManagerFactory

使用spring自动注入entitymanger(如果用EJB的话有容器注入),由于有两个数据源,定义两个EM

?

配置 1.4.1 ? intf EntityManagerFactory

<bean id="emf_intf" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">

??? <property name="persistenceUnitName" value="intf"/>

</bean>

?

?

?

配置 1.4.1 ? cx EntityManagerFactory

<bean id="emf_cx" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">

??? <property name="persistenceUnitName" value="cx"/>

</bean>

?

5、配置JTA事务管理器

配置JTA事务管理器,并自动注入到业务层

?

配置 1.5.1 ? JTA事务管理器

<!-- 事务管理器配置-->

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" />

?

配置 1.5.2 ? 事务传播级别设置

<!-- aop事务属性设置-->

<aop:config>

??? <aop:advisor pointcut="execution(* com.rbc.lcp..*.service.*Impl.*(..))" advice-ref="txAdvice"/>

</aop:config>

?? <tx:advice id="txAdvice">

??? <tx:attributes>

?????? <tx:method name="*" propagation="REQUIRED" rollback-for="Exception,RuntimeException" />

??? </tx:attributes>

</tx:advice>

?

配置 1.5.3 ? 事务自动注入设置

<!-- 使用annotation注入事务 -->

<tx:annotation-driven transaction-manager="transactionManager" />

?

6、配置Spring Data JPA

定义项目中各模块使用哪个数据源,将EM注入到对应的模块中。

?

配置 1.6.1 ? 模块1使用数据库源1(intf)

<jpa:repositories base-package="com.rbc.lcp.manager.**.repository"

?? entity-manager-factory-ref="emf_intf"

?? transaction-manager-ref="transactionManager"

?? />

?

配置 1.6.2 ? 模块2使用数据库源2(cx)

<jpa:repositories base-package="com.rbc.lcp.manager2.**.repository"

?? entity-manager-factory-ref="emf_cx"

?? transaction-manager-ref="transactionManager"

?? />

?

二、Atomikos实现JTA

使用atomikos就不需求依赖容器,这样可以使用tomcat,方便日常开发测试,和wildfly配置上大同小异,主要是数据源和事务管理器上差别较大。

由于项目使用的是hibernate4,所以需要atomikos4的支持,网上的教程都是atomikos3+hibernate3,写本文时atomikos4只是测试版,还没发布正式稳定版,资料很少,所以也花了不少时间才配置成功。

1、安装atomikos

配置 2.1.1 ? 在工程pom.xml中引入atomikos依赖

<dependency>

?? <groupId>com.atomikos</groupId>

?? <artifactId>atomikos-util</artifactId>

?? <version>4.0.0M4</version>

</dependency>

<dependency>

?? <groupId>com.atomikos</groupId>

?? <artifactId>transactions-api</artifactId>

?? <version>4.0.0M4</version>

</dependency>

<dependency>

?? <groupId>com.atomikos</groupId>

?? <artifactId>transactions-jta</artifactId>

?? <version>4.0.0M4</version>

</dependency>

<dependency>

?? <groupId>com.atomikos</groupId>

?? <artifactId>transactions</artifactId>

?? <version>4.0.0M4</version>

</dependency>

<dependency>

?? <groupId>com.atomikos</groupId>

?? <artifactId>transactions-jdbc</artifactId>

?? <version>4.0.0M4</version>

</dependency>

<dependency>

?? <groupId>com.atomikos</groupId>

?? <artifactId>transactions-hibernate4</artifactId>

?? <version>4.0.0M4</version>

</dependency>

?

?

?

2、配置XA数据源

配置 2.2.1 ? 配置数据源

<!-- 两个数据源的通用配置,方便下面直接引用 -->

<bean id="abstractXADataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"

??? init-method="init" destroy-method="close" abstract="true"? depends-on="txService">

??? <property name="minPoolSize" value="10" />

??? <property name="maxPoolSize" value="30" />

</bean>

?

<!-- 配置第一个数据源 -->

<bean id="intf_ds" parent="abstractXADataSource">

??? <!-- value只要各个数据源不同就行,随便取名 -->

??? <property name="uniqueResourceName" value="oracle/intf" />

??? <property name="xaDataSourceClassName"

??????? value="oracle.jdbc.xa.client.OracleXADataSource" />

??? <property name="xaProperties">

??????? <props>

??????????? <prop key="URL">jdbc:oracle:thin:@127.0.0.1:1521:orcl</prop>

??????????? <prop key="user">intf</prop>

??????????? <prop key="password">intf</prop>

??????? </props>

??? </property>

</bean>

?

<!-- 配置第二个数据源 -->

<bean id="cx_ds" parent="abstractXADataSource">

??? <!-- value只要各个数据源不同就行,随便取名 -->

??? <property name="uniqueResourceName" value="oracle/cx" />

??? <property name="xaDataSourceClassName"

??????? value="oracle.jdbc.xa.client.OracleXADataSource" />

??? <property name="xaProperties">

??????? <props>

??????????? <prop key="URL">jdbc:oracle:thin:@127.0.0.1:1521:orcl</prop>

??????????? <prop key="user">congxing</prop>

??????????? <prop key="password">congxing</prop>

??????? </props>

??? </property>

</bean>

?

3、配置JPA-persistence.xml

配置JPA持久化单元,注意和wildfly的区别,这里并不需要指定数据源。

?

配置 2.3.1 ? intf持久化单元

<persistence-unit name="intf" transaction-type="JTA">

</persistence-unit>

?

配置 2.3.2 ?cx持久化单元

<persistence-unit name="cx" transaction-type="JTA">

</persistence-unit>

?

4、配置EntityManagerFactory

注意和wildfly的区别,数据源也在这里配置

?

配置 2.4.1 ? intf EntityManagerFactory

<bean id="emf_intf"

??? class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

??? <property name="jtaDataSource" ref="intf_ds" />

??? <property name="persistenceUnitName" value="intf" />

??? <property name="jpaVendorAdapter">

?????? <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">

?????????? <property name="databasePlatform"

value="org.hibernate.dialect.Oracle10gDialect" />

?????? </bean>

??? </property>

??? <property name="jpaPropertyMap">

?????? <props>

?????????? <prop key="hibernate.current_session_context_class">jta</prop>

?????????? <prop key="javax.persistence.transactionType">jta</prop>

?????????? <prop key="hibernate.transaction.jta.platform">

?????????? com.atomikos.icatch.jta.hibernate4.AtomikosPlatform

?????????? </prop>

?????????? <prop key="hibernate.search.autoregister_listeners">false</prop>

?????? </props>

??? </property>

</bean>

?

配置 2.4.1 ? cx EntityManagerFactory

<bean id="emf_cx"

??? class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

??? <property name="jtaDataSource" ref="cx_ds" />

??? <property name="persistenceUnitName" value="cx" />

??? <property name="jpaVendorAdapter">

?????? <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">

?????????? <property name="databasePlatform"

????????????? value="org.hibernate.dialect.Oracle10gDialect" />

?????? </bean>

??? </property>

??? <property name="jpaPropertyMap">

?????? <props>

?????????? <prop key="hibernate.current_session_context_class">jta</prop>

?????????? <prop key="javax.persistence.transactionType">jta</prop>

?????????? <prop key="hibernate.transaction.jta.platform">

?????????? com.atomikos.icatch.jta.hibernate4.AtomikosPlatform

?????????? </prop>

?????????? <prop key="hibernate.search.autoregister_listeners">false</prop>

?????? </props>

??? </property>

</bean>

?

5、配置JTA事务管理器

配置 2.5.1 ? JTA事务管理器

<bean id="txService" class="com.atomikos.icatch.config.UserTransactionServiceImp"

??? init-method="init" destroy-method="shutdownWait">

</bean>

?

<bean id="txManager" class="com.atomikos.icatch.jta.UserTransactionManager"

??? depends-on="txService" />

?

<bean id="userTx" class="com.atomikos.icatch.jta.UserTransactionImp"

??? depends-on="txService" />

?

<bean id="transactionManager"

??? class="org.springframework.transaction.jta.JtaTransactionManager">

??? <property name="userTransaction" ref="userTx"></property>

??? <property name="transactionManager" ref="txManager"></property>

</bean>

?

配置 2.5.2 ? 事务传播级别设置

<!-- aop事务属性设置-->

<aop:config>

??? <aop:advisor pointcut="execution(* com.rbc.lcp..*.service.*Impl.*(..))" advice-ref="txAdvice"/>

</aop:config>

?? <tx:advice id="txAdvice">

??? <tx:attributes>

?????? <tx:method name="*" propagation="REQUIRED" rollback-for="Exception,RuntimeException" />

??? </tx:attributes>

</tx:advice>

?

配置 2S.5.3 ? 事务自动注入设置

<!-- 使用annotation注入事务 -->

<tx:annotation-driven transaction-manager="transactionManager" />

?

6、配置Spring Data JPA

和前面wildfly一样的,就不贴了。

?

?

参考资料:

http://www.ibm.com/developerworks/cn/java/j-lo-jta/

http://blog.trixi.cz/2011/11/jta-transaction-manager-atomikos-or-bitronix/

https://wiki.kuali.org/display/KULRICE/Replacing+JOTM+and+XAPool+with+Atomikos

?

?

JTA分布式事务实践

原文:http://hzy0769.iteye.com/blog/2294249

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!