开发传统应用遇到的最大问题就是多数据源的事务一致性问题, 下面介绍一种常用的分布式事务处理方式的使用
开发环境:Eclipse+Java1.7 + tomcat7, 另外使用到的开源框架 Spring3.X
提到分布式事务大家首先想到的肯定是jta,我们用到的就是基于jta的一种实现atomikos,下面就介绍一下他的使用
1、 依赖的jar
<!--atomikos 分布式事务依赖 --> <dependency> <groupId>com.atomikos</groupId> <artifactId>transactions-jta</artifactId> <version>${atomikos.version}</version> <optional>true</optional> </dependency> <dependency> <groupId>com.atomikos</groupId> <artifactId>transactions-jdbc</artifactId> <version>${atomikos.version}</version> <optional>true</optional> </dependency> <dependency> <groupId>javax.transaction</groupId> <artifactId>jta</artifactId> <version>${jta.version}</version> <optional>true</optional> </dependency> <!--数据源的连接池--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.9</version> </dependency>
2、 配置数据源
数据源连接池,必须是支持XA标准的连接池,什么是XA标准呢?
XA协议由Tuxedo首先提出的,并交给X/Open组织,作为资源管理器(数据库)与事务管理器的接口标准。目前,Oracle、Informix、DB2和Sybase等各大数据库厂家都提供对XA的支持。XA协议采用两阶段提交方式来管理分布式事务。XA接口提供资源管理器与事务管理器之间进行通信的标准接口。XA协议包括两套函数,以xa_开头的及以ax_开头的。
以下的函数使事务管理器可以对资源管理器进行的操作:
1)xa_open,xa_close:建立和关闭与资源管理器的连接。
2)xa_start,xa_end:开始和结束一个本地事务。
3)xa_prepare,xa_commit,xa_rollback:预提交、提交和回滚一个本地事务。
4)xa_recover:回滚一个已进行预提交的事务。
5)ax_开头的函数使资源管理器可以动态地在事务管理器中进行注册,并可以对XID(TRANSACTION IDS)进行操作。
6)ax_reg,ax_unreg;允许一个资源管理器在一个TMS(TRANSACTION MANAGER SERVER)中动态注册或撤消注册。
<!--dataSource--> <bean id="dataSource1" class="com.alibaba.druid.pool.xa.DruidXADataSource" init-method="init" destroy-method="close"> <!-- 基本属性 url、user、password --> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <!-- 配置初始化大小、最小、最大 --> <property name="initialSize" value="${jdbc.initialSize}" /> <property name="minIdle" value="${jdbc.minIdle}" /> <property name="maxIdle" value="${jdbc.maxIdle}" /> <property name="maxActive" value="${jdbc.maxActive}" /> <!-- 配置获取连接等待超时的时间 --> <property name="maxWait" value="${jdbc.maxWait}"/> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}" /> <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}" /> <property name="validationQuery" value="${jdbc.validationQuery}" /> <property name="testWhileIdle" value="${jdbc.testWhileIdle}" /> <property name="testOnBorrow" value="${jdbc.testOnBorrow}" /> <property name="testOnReturn" value="${jdbc.testOnReturn}" /> <property name="filters" value="${jdbc.filters}" /> </bean> <bean id="dataSource2" class="com.alibaba.druid.pool.xa.DruidXADataSource" init-method="init" destroy-method="close"> <!-- 基本属性 url、user、password --> <property name="url" value="${jdbc1.url}" /> <property name="username" value="${jdbc1.username}" /> <property name="password" value="${jdbc1.password}" /> <!-- 配置初始化大小、最小、最大 --> <property name="initialSize" value="${jdbc.initialSize}" /> <property name="minIdle" value="${jdbc.minIdle}" /> <property name="maxIdle" value="${jdbc.maxIdle}" /> <property name="maxActive" value="${jdbc.maxActive}" /> <!-- 配置获取连接等待超时的时间 --> <property name="maxWait" value="${jdbc.maxWait}"/> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}" /> <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}" /> <property name="validationQuery" value="${jdbc.validationQuery}" /> <property name="testWhileIdle" value="${jdbc.testWhileIdle}" /> <property name="testOnBorrow" value="${jdbc.testOnBorrow}" /> <property name="testOnReturn" value="${jdbc.testOnReturn}" /> <property name="filters" value="${jdbc.filters}" /> </bean>
3、强数据源指定到AtomikosDataSourceBean中,再有该类的对象向DAO层提供数据源服务
配置如下
datasource1
<bean id="xaDataSource1" class="com.atomikos.jdbc.AtomikosDataSourceBean" destroy-method="close"> <property name="xaDataSource" ref="dataSource1"/> <property name="uniqueResourceName" value="dataSource1"/> <property name="xaDataSourceClassName" value="com.alibaba.druid.pool.xa.DruidXADataSource"/> <property name="xaProperties"> <props> <prop key="serverName">test</prop> <prop key="portNumber">test</prop> <prop key="databaseName">test</prop> <prop key="user">test</prop> <prop key="password">test</prop> </props> </property> </bean>
dataSource2
<bean id="xaDataSource2" class="com.atomikos.jdbc.AtomikosDataSourceBean" destroy-method="close"> <property name="xaDataSource" ref="dataSource2"/> <property name="uniqueResourceName" value="dataSource2"/> <property name="xaDataSourceClassName" value="com.alibaba.druid.pool.xa.DruidXADataSource"/> <property name="xaProperties"> <props> <prop key="serverName">test</prop> <prop key="portNumber">test</prop> <prop key="databaseName">test</prop> <prop key="user">test</prop> <prop key="password">test</prop> </props> </property> </bean>
3、将数据源托管到TranscationManager
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"> <description>UserTransactionImp</description> <property name="transactionTimeout" value="300"/> </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="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <description>JtaTransactionManager</description> <property name="transactionManager"> <ref bean="atomikosTransactionManager" /> </property> <property name="userTransaction"> <ref bean="atomikosUserTransaction" /> </property> <property name="allowCustomIsolationLevels" value="true"/> </bean>
4、定义切面
<tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="do*" propagation="REQUIRED" rollback-for="Throwable, Exception, RuntimeException" /> <tx:method name="query*" propagation="NOT_SUPPORTED" /> <tx:method name="load*" propagation="NOT_SUPPORTED" /> <tx:method name="find*" propagation="NOT_SUPPORTED" /> <tx:method name="*" read-only="true" propagation="SUPPORTS" /> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut expression="execution(* com.jl.net..service.*.*(..))" id="pointCut" /> <aop:advisor pointcut-ref="pointCut" advice-ref="txAdvice" /> <aop:aspect ref="serviceInterceptor" order="2"> <aop:around method="doAround" pointcut-ref="pointCut" /> </aop:aspect> </aop:config>
5、 jta.properties (路径跟log4j.properties一致就好)
这个文件不配置系统也能启动,因为有默认配置,个人建议配置一下。详细配置
com.atomikos.icatch.console_file_name = xam.out
com.atomikos.icatch.log_base_name = xamlog.log
com.atomikos.icatch.service = com.atomikos.icatch.standalone.UserTransactionServiceFactory
相关推荐
其中,Spring的分布式事务管理是其核心特性之一,它允许开发者在分布式系统环境中处理复杂的事务逻辑。本篇将深入探讨Spring如何实现分布式事务,以及涉及到的相关技术。 首先,分布式事务是指在多个数据库或者服务...
在Spring声明式事务中,主要涉及以下几个关键概念: 1. **@Transactional** 注解:这是Spring提供的一个用于标记在哪些方法上应用事务的注解。在方法上添加此注解,Spring就会根据配置自动开始、提交、回滚事务。...
Spring框架提供了一套完整的声明式事务管理、依赖注入、AOP(面向切面编程)等功能,使得开发者能够轻松地集成和管理各种组件。在消息队列的实现中,Spring框架可以用来配置和管理消息生产者和消费者,以及处理消息...
本资料包“基于Spring Boot的声明式和编程式分布式锁.zip”着重探讨了如何在Spring Boot环境中实现分布式锁,这对于处理多节点并发访问共享资源的问题至关重要。 首先,我们要理解分布式锁的概念。分布式锁是一种...
本项目"java+spring+mybatis+mysql+RuoYi-atomikos-实现分布式事务.zip"是一个基于若依(RuoYi)框架改造的多模块分布式事务解决方案,它利用了Atomikos这一强大的分布式事务管理器。以下将详细解析这个项目的知识点...
在本项目中,Spring被用来协调各个组件,并提供声明式事务管理。Spring支持JTA(Java Transaction API),这是一个Java标准,用于定义应用程序与事务管理器之间的接口,使得在分布式环境中进行事务处理变得可能。 ...
在EJB或JTA环境中,Spring也可以作为容器的一部分,利用JTA(Java Transaction API)进行全局的分布式事务管理。这种方式适用于多数据源环境,能处理跨越多个数据库的事务。 5. 自动事务管理: Spring在某些特定...
在本项目中,"基于Spring AOP 的声明式和编程式分布式锁,支持RedisTemplate、Redisson、Zookeeper" 提供了一种灵活且高效的解决方案。 首先,我们要理解Spring AOP(面向切面编程)的概念。AOP允许开发者定义“切...
总的来说,Spring事务管理通过其强大的声明式事务处理能力和对各种事务策略的支持,使得开发者能够轻松地在应用程序中实现高效、一致的事务处理。通过理解并合理运用上述知识点,开发者可以构建出稳定、健壮的分布式...
Spring声明式事务是Spring框架中的一种事务管理方式,它允许开发者在不编写任何事务管理代码的情况下,通过配置来控制事务的边界。这种方式极大地简化了事务管理,使得业务逻辑代码和事务控制相分离,提高了代码的...
6. **分布式事务**:Spring Cloud Data Flow或Seata用于解决分布式环境下的事务一致性问题,确保数据的一致性和准确性。 7. **服务间通信**:使用Feign进行声明式的服务调用,简化了服务间的通信代码。 8. **消息...
本资源包含两个文件:“Spring声明式事务处理.wrf”和“testtrans”,很可能是示例代码或者测试用例,用于演示如何在Java应用中使用Spring进行声明式事务处理。 首先,让我们深入理解声明式事务处理的概念。声明式...
在Spring 4.1.7版本中,我们可以利用其声明式事务管理来简化分布式事务的实现。通过配置@Transactional注解,可以在方法级别声明事务边界,Spring会自动管理事务的开始、提交或回滚。 Atomikos是一款开源的事务管理...
通过上述步骤,Spring Cloud应用能够轻松地实现分布式事务管理,提升了系统的可扩展性和稳定性。不过,值得注意的是,尽管TX-LCN简化了分布式事务的实现,但在实际应用中仍需考虑性能、网络延迟、故障恢复等问题,并...
1. **统一接口**:无论是编程式还是声明式事务管理,都基于`PlatformTransactionManager`接口,使得事务管理的实现更为一致和简洁。 2. **灵活性**:Spring支持多种事务管理方式,可以根据实际需求选择最合适的方式...
Spring的声明式事务管理允许开发者通过配置XML或使用注解来控制事务边界,而无需显式编写事务管理代码。此外,Spring还支持编程式事务管理,允许开发者在代码中手动开始、提交、回滚事务。 **WebLogic Server**是一...
1. "Spring声明式事务配置管理方法 - 一个无聊的人 - 博客园.mht":这篇文章很可能深入讲解了如何在Spring中使用声明式事务,包括但不限于@Transaction注解的使用,以及在XML配置文件中设置事务属性,如propagation...
声明式事务管理是Spring中最常用的事务管理方式,它将事务逻辑与业务代码分离,提高了代码的可读性和可维护性。主要有两种实现方式: - **基于XML的声明式事务管理** 在Spring的配置XML文件中,通过`<tx:advice>...