最近一直在研究怎么实现分布式事务,花了不少时间,测试工程启停测试了无数次,最终实现的时候其实也就是写一些配置文件,对于工程代码没什么影响。目前研究还不是很深入,对于全面崩溃恢复如何实现和测试还不清楚。本文先介绍基础的实现。
当业务需要在一个事务中操作多个不同的资源,例如多个数据库,消息队列,缓存等,那么就需要使用分布式事务了。在java中一般建议使用JTA,这样开发人员就不用关心什么叫XA协议,什么是两阶段提交协议。要使用JTA需要容器的支持,例如使用JBOSS,WebSphere;或者使用第三方组件例如JOTM、Atomikos。
JBOSS AS现在改名叫Wildfly了,以便和JBOSS EAP区分,后文我也改叫Wildfly。JOTM看起来是个死项目,我不打算使用。
由于目前开发框架基于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> |
打开wildfly的standalone.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事务管理器,并自动注入到业务层
<!-- 事务管理器配置--> <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
相关推荐
本项目“spring+jotm+ibatis+mysql实现JTA分布式事务”旨在利用这些技术来确保在分布式环境中的数据一致性。下面将详细介绍这个项目所涉及的知识点。 首先,Spring框架是Java开发中最常用的应用框架之一,它提供了...
在IT行业中,分布式事务处理是复杂系统设计的关键环节,特别是在大型企业级应用中。...同时,这个例子也能帮助开发者了解在实际项目中如何配置和使用这些组件,提升对分布式事务处理的理解和实践能力。
总之,JTA分布式事务的示例代码展示了如何在Java环境中处理跨多个数据源的事务,保证在分布式系统中的数据一致性。理解和掌握JTA对于构建高可用、高并发的分布式应用至关重要。通过分析和实践这样的示例代码,开发者...
1-1 导学-分布式事务实践 第2章 事务原则与实现 介绍了事务的四大原则,并通过实例介绍数据库实现事务的方法,以及使用JDBC实现事务的方法。 2-1 事务原则与实现:事务 2-2 事务原则与实现:SQL事务 2-3 事务原则与...
分布式事务是现代企业级应用中不可或缺的一部分,尤其是在大数据和微服务架构中,它确保了在多个数据库或资源管理系统中的数据...在实践中,你可以根据自己的环境和需求进行适当的调整,以实现高效的分布式事务管理。
Java分布式事务是大型分布式系统中不可或缺的一个重要组成部分,它确保在多个网络节点间的数据操作能够保持一致性和完整性。...通过学习和理解这些示例,开发者可以更好地掌握Java分布式事务的原理和实践。
本篇文章将探讨如何在Java环境中,利用Spring框架和Atomikos这样的第三方工具实现分布式事务管理,即JTA(Java Transaction API)的实践。 JTA是Java平台提供的一种标准API,用于管理跨越多个资源(如数据库、消息...
在分布式系统中,确保数据的一致性和完整性是至关重要的,这就是分布式事务的职责所在。...对于理解和实践分布式事务,以及深入研究Spring Boot、MyBatis和Atomikos的开发者来说,这是一个宝贵的资源。
分布式事务是计算机科学中涉及数据库管理系统的一个重要概念,特别是在大型企业级应用和互联网服务中,其目的是确保在多个网络节点间的数据操作一致性。在分布式系统中,数据可能分布在不同的服务器或存储设备上,...
总结来说,"Atomikos实现分布式事务"是一个关键的技术实践,它利用Java的JTA标准,结合Atomikos库,实现了在Web项目中对多个数据库进行统一的事务管理,确保了业务操作的原子性和一致性,从而提高了系统整体的可靠性...
综上所述,大规模SOA系统中的分布式事务处理是一门深奥且实践性的技术,涵盖了从理论到实践的多个层面。理解并掌握这些关键技术对于构建可靠、高性能的分布式系统至关重要。在实际应用中,应根据业务需求和系统特性...
Atomikos是一款开源的Java事务管理器,它实现了JTA(Java Transaction API)规范,能够支持跨多个数据库的分布式事务。 Spring Boot集成Atomikos进行分布式事务管理,主要步骤包括: 1. 引入依赖:在项目中添加...
通常,我们可以使用`JtaTransactionManager`配合Atomikos、Bitronix等JTA实现来处理分布式事务。以下是一个简单的示例: ```java @Configuration @EnableTransactionManagement public class TransactionConfig { ...
- 分布式事务框架:如Atomikos、Bitronix等,提供了基于JTA的分布式事务管理。 - Spring框架的事务管理:Spring的PlatformTransactionManager接口提供了对本地和分布式事务的支持,如DataSourceTransactionManager...
本案例主要探讨如何利用Spring Boot、Atomikos、JTA(Java Transaction API)、Hibernate以及MyBatis,结合MySQL数据库,实现一个跨数据源的分布式事务解决方案。 首先,Spring Boot是一个基于Spring框架的快速开发...
分布式数据源、数据源的动态查找以及分布式事务的...通过学习和实践这个项目,开发者可以深入理解如何在Spring环境中利用JTA和MyBatis实现分布式数据源和分布式事务,这对于构建高可用、高扩展性的企业级应用至关重要。
此外,还可能涵盖如何在具体的技术栈如Java的JTA(Java Transaction API)、Spring框架的Atomikos、Seata等中实现分布式事务管理。 五、最佳实践与案例分析 1. **CAP理论**:在分布式系统设计中,通常需要在一致性...
对于分布式事务,我们可以使用JTA(Java Transaction API)配合X/Open XA规范实现两阶段提交(2PC)。 MySQL作为广泛使用的SQL数据库,虽然默认不支持分布式事务,但可以通过InnoDB存储引擎启用行级锁和事务支持。...
因此,多数据源分布式事务管理成为了必不可少的技术。本教程将聚焦于如何利用Spring 3.0、Hibernate ORM框架以及Atomikos这个开源事务管理器来实现高效、可靠的多数据源分布式事务处理。 **Spring 3.0**: Spring是...