spring boot 2.x+mybatis-plus+多源数据库实现分布式事务

spring boot 2.x+mybatis-plus+多源数据库实现分布式事务
上一篇说到利用AOP通过注解方式实现多源数据库的动态切换,本篇文章为大家讲解在多数据源下实现分布式事务
在实际开发中,我们会遇到一个service中实现多个库的CRUD,但是我spring 提供的事务注解只支持单库,这时候如果我们遇到A库表插入成功,B库表插入失败,但是数据不会回滚,在A表容易产生脏数据。这种情况下就很需要分布式事务在分别处理。spring+boot的分布式事务我们利用jta来实现分布式事务
首先导入依赖

		<!-- JPA -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jta-atomikos</artifactId>
		</dependency>

JTA的优点就是能够支持多数据库事务同时事务管理,满足分布式系统中的数据的一致性.但是也有对应的弊端:

  1. 两阶段提交
  2. 事务时间太长,锁数据太长
  3. 低性能,低吞吐量
    具体不懂的可以百度2PC和3PC阶段性提交

-----------------------------------------------华丽的分割线-----------------------------------------------

实现分布式事务主要实现原理是创建一个全局事务,然后由各个本地事务去阶段性提交,最后由全局事务统一提交

@Configuration
public class DataSourceConfig {
    @Value("${spring.datasource.type:com.alibaba.druid.pool.xa.DruidXADataSource}")
    String xaDataSourceClassName;
    @Value("${mybatis-plus.mapper-locations}")
    private String mapperLocations;
    
    @Primary
    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dataSource)
            throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setTransactionFactory(new MultiDataSourceTransactionFactory());
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        bean.setMapperLocations(resolver.getResources(mapperLocations));
        return bean.getObject();
    }
    @Bean(name="sqlSessionTemplate")
    @Primary
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
 /**
     * 分布式事务使用JTA管理,只需配置一个JtaTransactionManager
     * @return
     */
    /*atomikos事务管理器*/
    public UserTransactionManager userTransactionManager() {
        UserTransactionManager userTransactionManager = new UserTransactionManager();
        userTransactionManager.setForceShutdown(true);
        return userTransactionManager;
    }

    public UserTransactionImp userTransactionImp() throws SystemException {
        UserTransactionImp userTransactionImp = new UserTransactionImp();
        userTransactionImp.setTransactionTimeout(5000);
        return userTransactionImp;
    }

    @Bean
    public JtaTransactionManager jtaTransactionManager() throws SystemException {
        JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();
        jtaTransactionManager.setTransactionManager(userTransactionManager());
        jtaTransactionManager.setUserTransaction(userTransactionImp());
        jtaTransactionManager.setAllowCustomIsolationLevels(true);
        return jtaTransactionManager;
    }

最后只须在对应的实现方法上加上注解就能实现分布式事务

@Transactional(rollbackFor = Exception.class)

PS:动态数据库切换可以参考我博客的上一篇文章

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值