SpringBoot多数据源中的分布式事务

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_37158722/article/details/103224786
            </div>
                                                <!--一个博主专栏付费入口-->
         
         <!--一个博主专栏付费入口结束-->
        <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-4a3473df85.css">
                                    <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-4a3473df85.css">
            <div class="htmledit_views" id="content_views">
                                        <p>虽然现在微服务越来越流行,我们的系统随之也拆分出来好多的模块功能。这样做的目的其实就是为了弥补单体架构中存在的不足。随着微服务的拆分,肯定设计到分库分表,但这之中肯定设计到分布式事务。最典型的例子就是<strong>银行转账</strong>,比如银行A给银行B转账500&nbsp;块钱,流程肯定是银行A-500,银行B+500,在这个过程<strong>要么都成功,要么都成仁</strong>。首先银行A和银行B的数肯定是在不同的数据库,如果在转账的过程中,银行A首先-500库钱之后,在银行B+500的时候出现了问题,如果事务不回滚,那么就会出现500块钱丢失的问题,也就是出现了<strong>事务一致性</strong>问题。</p>

 

 

JTA + Atomikos解决分布式事务

一、JTA

JTA(java Transaction API)是JavaEE 13 个开发规范之一。Java 事务API,允许应用程序执行分布式事务处理——在两个或多个网络计算机资源上访问并且更新数据。JDBC驱动程序的JTA支持极大地增强了数据访问能力。事务最简单最直接的目的就是保证数据的有效性,数据的一致性。

 

二、Atomikos

Atomikos是一个为Java平台提供增值服务的并且开源类事务管理器。

 

工作原理:分布式事务包括事务管理器和支持XA的资源管理器。资源管理器就是我们的DB,事务管理器就是承担调节和控制所有参与DB所设计到的事务。

个人理解:Atomikos 获取到数据库的连接之后,会屏蔽数据库底层的事务控制,然后全部交给 Atomikos,进行统一的调度和控制。

 

接下来,我们简单的做一个基于 SpringBoot 的分布式事务控制。

1、首先我们要引入需要引入的maven库

 


 
 
  1. <!--分布式事务-->
  2. <dependency>
  3.    <groupId>org.springframework.boot </groupId>
  4.    <artifactId>spring-boot-starter-jta-atomikos </artifactId>
  5. </dependency>

 

2、配置数据源

 

3、配置类

 

最主要的配置


 
 
  1. @Configuration
  2. @MapperScan(basePackages = "com.example.mapper.db1", sqlSessionFactoryRef = "db1SqlSessionFactory")
  3. public  class DB1DataSourcesConfig {
  4.      @Primary
  5.      @Bean(name = "db1DataSource")
  6.      public DataSource dataSource(DB1Config DB1Config) {
  7.          // 设置数据库连接
  8.         MysqlXADataSource mysqlXADataSource = new MysqlXADataSource();
  9.         mysqlXADataSource.setUrl(DB1Config.getUrl_jdbc());
  10.         mysqlXADataSource.setUser(DB1Config.getUsername());
  11.         mysqlXADataSource.setPassword(DB1Config.getPassword());
  12.         mysqlXADataSource.setPinGlobalTxToPhysicalConnection( true);
  13.          // 交给事务管理器进行管理
  14.         AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
  15.         atomikosDataSourceBean.setXaDataSource(mysqlXADataSource);
  16.         atomikosDataSourceBean.setUniqueResourceName( "db1DataSource");
  17.          return atomikosDataSourceBean;
  18.     }
  19.      @Primary
  20.      @Bean(name = "db1SqlSessionFactory")
  21.      public SqlSessionFactory sqlSessionFactory( @Qualifier("db1DataSource") DataSource dataSource) throws Exception {
  22.         SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
  23.         sessionFactoryBean.setDataSource(dataSource);
  24.         sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources( "classpath*:/mapper/db1/*.xml"));
  25.         org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
  26.         configuration.setMapUnderscoreToCamelCase( true);
  27.         sessionFactoryBean.setConfiguration(configuration);
  28.          return sessionFactoryBean.getObject();
  29.     }
  30.      @Primary
  31.      @Bean(name = "db1SqlSessionTemplate")
  32.      public SqlSessionTemplate sqlSessionTemplate( @Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
  33.          return new SqlSessionTemplate(sqlSessionFactory);
  34.     }
  35. }

 

这样基本就配置完了,这里我只写了一个数据库的配置,另外一个同这个一样,就是数据库信息变了而已。

4、测试

这里设计到两个数据的修改,学生姓名和学生分数成绩,这两个数据分别存储在不同的数据库。我们通过接口先修改用户信息,接着再修改用户的分数信息。

没有修改前的数据

我们先没不加事务,先看下如果再修改分数的时候出现异常,用户信息会不会回滚回去。

结果

首先代码在39行报错,如果按照我们的逻辑,如果修改分数失败,那么相应的用户的年龄修改也是不成功的,但是结果显示用户的年龄还是被修改了,显然这个接口并没有被分布式事务所管理。

 

 

我们先把数据改回原来,然后我们再把事务加上,看还不会出现这种问题。(方法上加@Transactional注解即可

结果

加了分布式事务之后,通过结果就可以看到,如果后面的结果出现了错误,前面的数据也是会进行回滚的,保证了事务的前后一致性,确保了数据的安全准确。

 

总结:以上就是  JTA + Atomikos  实现分布式事务的整个过程,相对实现功能来说还是比较简单的,以上的测试是基于单个的 SpringBoot 项目的,相对于真正的微服务来说,这样的方式我还没有进行测试,如果需要进行微服务之间的事务管理,也可以通过 mq 或者 dubbo 去进行事务的一致性管理。等以后研究了再来跟大家分享。

项目地址:https://github.com/liangbintao/distributed_transaction.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值