多数据源事务控制

多数据源事务控制

在多数据源下,由于涉及到数据库的多个读写。一旦发生异常就可能会导致数据不一致的情况,在这种情况希望使用事务进行回退。但是Spring的声明式事务在一次请求线程中只能使用一个数据源进行控制
但是对于多源数据库:
  1. 单一事务管理器(TransactionManager)无法切换数据源,需要配置多个TransactionManager。
  2. @Transactionnal是无法管理多个数据源的。 如果想真正实现多源数据库事务控制,肯定是需要分布式事务。 这里讲解多源数据库事务控制的一种变通方式。
@Bean
public DataSourceTransactionManager transactionManager1(DynamicDataSource dataSource){
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(dataSource);
return dataSourceTransactionManager;
}

 @Bean
 public DataSourceTransactionManager transactionManager2(DynamicDataSource dataSource){
 DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
 dataSourceTransactionManager.setDataSource(dataSource);
 return dataSourceTransactionManager;
 }

只使用主库TransactionManger

使用主库事务管理器,也就是说事务中产生异常时,只能回滚主库数据。但是因为数据操作顺序是先主后从,所以分一下三种情况:
  1. 主库插入时异常,主库未插成功,这时候从库还没来及插入,主从数据是还是一致的
  2. 主库插入成功,从库插入时异常,这时候在主库事务管理器监测到事务中存在异常,将之前插入的主库数据插入,主从数据还是一致的
  3. 主库插入成功,从库插入成功,事务结束,主从数据一致。
@Override
@WR("W")
public void save(Frend frend) {
frendMapper.save(frend);
//int a=1/0; 1.主库插入时异常,主库未插成功,这时候从库还没来及插入,主从数据是还是一致的
}

@Override
@WR("R")
@Transactional(
transactionManager = "transactionManager2",propagation= Propagation.REQUIRES_NEW)
public void saveRead(Frend frend) {
    frend.setName("xushu");
    frendMapper.save(frend);
    // int a=1/0; 2.主库插入成功,从库插入时异常,这时候在主库事务管理器监测到事务中存在异常,将之前插入的主库数据插入,主从数据还是一致的
  }

 @Override
 @Transactional(transactionManager = "transactionManager1")
 public void saveAll(Frend frend) {
     // 3. 无异常情况:主库插入成功,从库插入成功,事务结束,主从数据一致。
     FrendService self= (FrendService)AopContext.currentProxy();
     self.save(frend);
     self.saveRead(frend);
     //int a=1/0; 从库插入之后出现异常, 只能回滚主库数据 ,从库数据是无法回滚的 , 数据将不一致
 }
当然这只是理想情况,例外情况:
4.从库插入之后出现异常, 只能回滚主库数据 ,从库数据是无法回滚的 , 数据将不一致
5.从库数据插入成功后,主库提交,这时候主库崩溃了,导致数据没插入,这时候从库数据也是无法回滚的。这种方式可以简单实现多源数据库的事务管理,但是无法处理上述情况。

一个方法开启2个事务

spring编程式事务

 // 读‐‐ 写库
@Override
public void saveAll(Frend frend) {
    wtransactionTemplate.execute(wstatus ‐> {
    rtransactionTemplate.execute(rstatus ‐> {
        try{
            saveW(frend);
            saveR(frend);
            int a=1/0;
            return true;
            }
        catch (Exception e){
            wstatus.setRollbackOnly();
            rstatus.setRollbackOnly();
            return false;
        }
    });
        return true;
    });
}

spring声明式事务

@Transactional
@Transactional(transactionManager = "wTransactionManager")
public void saveAll(Frend frend) throws Exception {
    FrendService frendService = (FrendService) AopContext.currentProxy();
    frendService.saveAllR(frend);
}

@Transactional(transactionManager = "rTransactionManager",propagation = Propagation.REQUIRES_NEW )
    public void saveAllR(Frend frend) {
    saveW(frend);
    saveR(frend);
    int a = 1 / 0;
}
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值