上一篇介绍了分库分表插件,但是多库操作涉及到分布式事务问题,大家都知道分布式事务需要涉及到数据库XA驱动,oracle原本就支持,mysql在5.6版本支持了该属性,atomikos插件封装了该特性的一个中间件。现在来介绍一个atomikos的使用。
首先是jar包依赖,maven配置如下:
<dependency> <groupId>com.atomikos</groupId> <artifactId>transactions</artifactId> <version>4.0.4</version> </dependency> <dependency> <groupId>com.atomikos</groupId> <artifactId>transactions-api</artifactId> <version>4.0.4</version> </dependency> <dependency> <groupId>com.atomikos</groupId> <artifactId>atomikos-util</artifactId> <version>4.0.4</version> </dependency> <dependency> <groupId>com.atomikos</groupId> <artifactId>transactions-jdbc-deprecated</artifactId> <version>3.8.0</version> </dependency> <dependency> <groupId>com.atomikos</groupId> <artifactId>transactions-jta</artifactId> <version>4.0.4</version> </dependency> <dependency> <groupId>com.atomikos</groupId> <artifactId>transactions-jdbc</artifactId> <version>4.0.4</version> </dependency>
额外的还要增加jta的配置,使用jta管理spring事务:
<dependency> <groupId>javax.transaction</groupId> <artifactId>jta</artifactId> <version>1.1</version> </dependency>
然后是srping配置,由于需要使用atomikos数据源,所以对上一篇分库分表插件的数据源配置做了修改:
<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rdb="http://www.dangdang.com/schema/ddframe/rdb" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.dangdang.com/schema/ddframe/rdb http://www.dangdang.com/schema/ddframe/rdb/rdb.xsd" > <!-- 配置数据源 --> <bean name="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" destroy-method="close"> <!-- <property name="driverClassName" value="${jdbc.driverClassName}" /> --> <property name="uniqueResourceName" value="dataSource" /> <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" /> <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="50" /> <property name="maxIdleTime" value="60" /> </bean> <!-- 配置数据源 --> <bean name="master0" class="com.atomikos.jdbc.AtomikosDataSourceBean" destroy-method="close"> <!-- <property name="driverClassName" value="${jdbc.driverClassName}" /> --> <property name="uniqueResourceName" value="master0" /> <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" /> <property name="xaProperties"> <props> <prop key="user">${jdbc.username}</prop> <prop key="password">${jdbc.password}</prop> <prop key="url">jdbc:mysql://127.0.0.1:3306/demodb00</prop> </props> </property> <property name="minPoolSize" value="5" /> <property name="maxPoolSize" value="50" /> <property name="maxIdleTime" value="60" /> </bean> <!-- 配置数据源 --> <bean name="master1" class="com.atomikos.jdbc.AtomikosDataSourceBean" destroy-method="close"> <!-- <property name="driverClassName" value="${jdbc.driverClassName}" /> --> <property name="uniqueResourceName" value="master1" /> <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" /> <property name="xaProperties"> <props> <prop key="user">${jdbc.username}</prop> <prop key="password">${jdbc.password}</prop> <prop key="url">jdbc:mysql://127.0.0.1:3306/demodb01</prop> </props> </property> <property name="minPoolSize" value="5" /> <property name="maxPoolSize" value="50" /> <property name="maxIdleTime" value="60" /> </bean> <rdb:strategy id="idDbSharding" sharding-columns="id" algorithm-class="com.feng.splitdbtb.DbAlgorithm"/> <rdb:strategy id="idTbSharding" sharding-columns="id" algorithm-class="com.feng.splitdbtb.TbAlgorithm"/> <rdb:data-source id="wholeDataSource"> <rdb:sharding-rule data-sources="master0,master1"> <rdb:table-rules> <rdb:table-rule logic-table="user" actual-tables="user_${0..1}" database-strategy="idDbSharding" table-strategy="idTbSharding"/> </rdb:table-rules> </rdb:sharding-rule> </rdb:data-source> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="wholeDataSource" /> <property name="configLocation" value="classpath:mybatis-config.xml"/> <property name="mapperLocations" > <list> <value>classpath:com/feng/mapper/user/*.xml</value> </list> </property> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.feng.dao.user" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> </bean> <!-- 定义事务 --> <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="300" /> </bean> <bean id="springTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionManager"> <ref bean="atomikosTransactionManager" /> </property> <property name="userTransaction"> <ref bean="atomikosUserTransaction" /> </property> <property name="allowCustomIsolationLevels" value="true"/> </bean> <tx:advice id="txAdvice" transaction-manager="springTransactionManager"> <tx:attributes> <tx:method name="publish*" /> <tx:method name="save*" /> <tx:method name="add*" /> <tx:method name="update*" /> <tx:method name="insert*" /> <tx:method name="create*" /> <tx:method name="del*" /> <tx:method name="load*" /> <tx:method name="init*" /> <tx:method name="*" read-only="true"/> </tx:attributes> </tx:advice> <!-- AOP配置--> <aop:config> <aop:pointcut id="myPointcut" expression="execution(public * com.feng.service.impl.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut" /> </aop:config> <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean> </beans>
运行一下,看到以下日志的兄弟,说明已经成功了,内心一阵狂热,胸膛也挺直了。
[DEBUG][2017-04-17 09:58:27,821][com.atomikos.icatch.imp.CompositeTransactionImp]addParticipant ( XAResourceTransaction: 636F6D2E61746F6D696B6F732E737072696E672E6A6462632E746D313439323339343330373730353030303035:636F6D2E61746F6D696B6F732E737072696E672E6A6462632E746D35 ) for transaction com.atomikos.spring.jdbc.tm149239430770500005 [DEBUG][2017-04-17 09:58:27,821][com.atomikos.datasource.xa.XAResourceTransaction]XAResource.start ( 636F6D2E61746F6D696B6F732E737072696E672E6A6462632E746D313439323339343330373730353030303035:636F6D2E61746F6D696B6F732E737072696E672E6A6462632E746D35 , XAResource.TMNOFLAGS ) on resource master1 represented by XAResource instance com.mysql.jdbc.jdbc2.optional.JDBC4MysqlXAConnection@2c7e446d [DEBUG][2017-04-17 09:58:27,840][com.atomikos.icatch.imp.CompositeTransactionImp]registerSynchronization ( com.atomikos.jdbc.AtomikosConnectionProxy$JdbcRequeueSynchronization@1f21ef16 ) for transaction com.atomikos.spring.jdbc.tm149239430770500005 [DEBUG][2017-04-17 09:58:27,841][com.atomikos.jdbc.AtomikosConnectionProxy]atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@2015fa5c: calling prepareStatement(INSERT INTO user_1 (id, name, age) VALUES (?, ?, ?),1003,1007,1)... [DEBUG][2017-04-17 09:58:27,866][org.mybatis.spring.SqlSessionUtils]Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@ac88402] [DEBUG][2017-04-17 09:58:27,866][org.mybatis.spring.SqlSessionUtils]Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@ac88402] [DEBUG][2017-04-17 09:58:27,866][org.mybatis.spring.SqlSessionUtils]Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@ac88402] [DEBUG][2017-04-17 09:58:27,866][org.springframework.jdbc.datasource.DataSourceUtils]Returning JDBC Connection to DataSource [DEBUG][2017-04-17 09:58:27,866][com.atomikos.jdbc.AtomikosConnectionProxy]atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@2015fa5c: close()... [DEBUG][2017-04-17 09:58:27,866][com.atomikos.datasource.xa.XAResourceTransaction]XAResource.end ( 636F6D2E61746F6D696B6F732E737072696E672E6A6462632E746D313439323339343330373730353030303035:636F6D2E61746F6D696B6F732E737072696E672E6A6462632E746D35 , XAResource.TMSUCCESS ) on resource master1 represented by XAResource instance com.mysql.jdbc.jdbc2.optional.JDBC4MysqlXAConnection@2c7e446d [DEBUG][2017-04-17 09:58:27,885][org.springframework.transaction.jta.JtaTransactionManager]Initiating transaction rollback [DEBUG][2017-04-17 09:58:27,887][com.atomikos.datasource.xa.XAResourceTransaction]XAResource.rollback ( 636F6D2E61746F6D696B6F732E737072696E672E6A6462632E746D313439323339343330373730353030303035:636F6D2E61746F6D696B6F732E737072696E672E6A6462632E746D35 ) on resource master1 represented by XAResource instance com.mysql.jdbc.jdbc2.optional.JDBC4MysqlXAConnection@2c7e446d [DEBUG][2017-04-17 09:58:27,906][com.atomikos.icatch.imp.CompositeTransactionImp]rollback() done of transaction com.atomikos.spring.jdbc.tm149239430770500005 [DEBUG][2017-04-17 09:58:27,907][com.atomikos.icatch.imp.CompositeTransactionImp]rollback() done of transaction com.atomikos.spring.jdbc.tm149239430770500005
最后提醒一下,业务的相关方法一定不要捕获异常,抛出来RunTimeException也不行,否则atomikos不能回滚,具体原因不明。
相关推荐
Spring Boot作为轻量级的Java开发框架,结合Atomikos这样的分布式事务管理器,可以有效地解决这些问题。本文将深入探讨如何在Spring Boot项目中实现Atomikos分布式事务以及动态数据源切换的两种示例。 首先,我们...
本文将详细讲解"springboot-jpa atomikos 分布式事务管理"这一主题,以及如何在SpringBoot 2.0.5版本中结合JPA、Hibernate和MyBatis实现多数据库事务控制。 首先,SpringBoot是一个简化Spring应用开发的框架,它...
本项目"java+spring+mybatis+mysql+RuoYi-atomikos-实现分布式事务.zip"是一个基于若依(RuoYi)框架改造的多模块分布式事务解决方案,它利用了Atomikos这一强大的分布式事务管理器。以下将详细解析这个项目的知识点...
Spring框架提供了强大的支持来处理分布式事务,而Atomikos是一个开源的事务管理器,专门用于处理JTA(Java Transaction API)事务,尤其适用于微服务和分布式环境。本教程将探讨如何结合Spring和Atomikos来实现...
总结来说,"Atomikos实现分布式事务"是一个关键的技术实践,它利用Java的JTA标准,结合Atomikos库,实现了在Web项目中对多个数据库进行统一的事务管理,确保了业务操作的原子性和一致性,从而提高了系统整体的可靠性...
7. **分布式事务的新趋势**:随着微服务架构的流行,新型的分布式事务解决方案如Seata(前身是Fescar)和Atomikos等应运而生,它们提供了更高效、更灵活的分布式事务管理。 在实际的"java分布式事务demo"中,可能会...
Atomikos分布式事务DEMO是一个基于Spring、MyBatis、MySQL和Tomcat的示例项目,主要用于演示和验证分布式事务的处理能力。分布式事务在现代企业级应用中扮演着重要角色,尤其是在处理跨多个数据库或服务的数据一致性...
Druid是一个优秀的数据库连接池组件,而AtomikosDataSource则是处理分布式事务的重要工具。下面我们将详细探讨如何利用Spring、Druid和AtomikosDataSource来实现这些功能。 1. **Spring框架与数据源** Spring提供...
Atomikos是一个开源的事务处理系统,专门设计用于在Java应用程序中实现分布式事务管理。它提供了JTA(Java Transaction API)的实现,使得开发者能够在不同的数据源之间进行复杂的事务操作,确保数据的一致性和完整...
windows xp 下 安装sqlserver分布式事务(atomikos )所需要的补丁
本教程将聚焦于如何利用Spring 3.0、Hibernate ORM框架以及Atomikos这个开源事务管理器来实现高效、可靠的多数据源分布式事务处理。 **Spring 3.0**: Spring是Java开发中最广泛使用的轻量级框架之一,它提供了一个...
本文将详细讲解如何利用Spring Boot、Atomikos、JPA(Java Persistence API)以及MySQL来实现JTA(Java Transaction API)分布式事务。 首先,Spring Boot是一个轻量级的框架,它简化了基于Spring的应用程序开发...
若依框架通过引入成熟的分布式事务解决方案,如Seata、Atomikos等,来解决这一问题。 3. **若依框架中的分布式事务配置** 在若依框架中,配置分布式事务通常涉及以下几个步骤: - 添加依赖:在项目的pom.xml或...
Spring框架提供了多种实现分布式事务管理的方式,其中一种是通过集成第三方工具如Atomikos来实现。Atomikos是一个开源的事务处理服务,支持JTA(Java Transaction API),能很好地处理分布式环境中的ACID(原子性、...
SpringBoot作为一款轻量级的框架,提供了便捷的多数据源配置和分布式事务管理方案,使得开发者能够高效地管理和操作不同的数据库。本文将详细探讨SpringBoot如何实现多数据源以及分布式事务。 首先,我们要理解什么...
【分布式事务概述】 分布式事务是指在分布式环境下,跨越多个数据源的操作需要保证一致性,即所有操作要么全部成功,要么全部失败。这是因为业务功能往往需要横跨多个服务和数据库,而这些服务和数据库可能位于不同...
Atomikos是一个强大的开源分布式事务处理框架,专为Java企业级应用设计,它提供了一种在分布式环境中确保数据一致性的方式。在大型系统中,尤其是在微服务架构或云环境下的复杂业务场景,分布式事务处理是必不可少的...
Atomikos 是一个开源的事务管理器,特别适用于 Spring 应用,提供了强大的分布式事务处理能力。这篇内容将深入探讨如何在 Spring 中集成 Atomikos 实现分布式事务的提交,并通过示例进行讲解。 Atomikos 是一款遵循...
SpringBoot集成Atomikos使用Oracle数据库mybatisSpringBoot集成Atomikos使用Oracle数据库mybatisSpringBoot集成Atomikos使用Oracle数据库mybatisSpringBoot集成Atomikos使用Oracle数据库mybatis