@DS注解进行数据源切换下的@Transactional事务不起作用的方案

项目场景:

搭配使用 - @DS注解,@Transactional注解

微服务项目中,使用Mybatis plus的@DS注解进行数据源切换,@Transactional事务不起作用

1.Mapper

@DS(DsName.EHP)
public interface CustomerMapper extends BaseMapper<Customer> {

    Page<CmsCustomerListBO> getPage(@Param("page") IPage<PromoterMangerRequestBO> page, @Param("ew") Wrapper<PromoterMangerRequestBO> entityWrapper);

}

2.业务类

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setStatus(Long id, Integer status) throws BusinessException {
        if(id == null || status == null){
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR);
        }
        Customer customer = baseMapper.selectById(id);
        if (customer == null) {
            throw new BusinessException(BaseExceptionCodes.DATA_ERR);
        }
        customer.setStatus(status);
        customer.setChangedBy(SecurityUtils.getCurrentUsername());
        customer.setChangedAt(new Date());
        customerMapper.updateById(customer);

3.报错信息提示

### Error querying database.  Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'adb.customer' doesn't exist
### The error may exist in com/naiterui/ehp/bs/agent/modules/customer/mapper/CustomerMapper.java (best guess)
### The error may involve defaultParameterMap
### The error occurred while setting parameters

原因分析:

主要分析开发常见的三种情况

1.不使用@Transactional,数据源切换正常,但是事务无效
2.使用@Transactional,数据源没有切换
3.使用@Transactional(propagation = Propagation.REQUIRES_NEW),数据源切换,且事务有效


解决方案:

@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
@DS(DsName.EHP)

1.开启事务的同时,会从数据库连接池获取数据库连接;
2.如果内层的service使用@DS切换数据源,只是又做了一层拦截,但是并没有改变整个事务的连接
3.在这个事务内的所有数据库操作,都是在事务连接建立之后,所以会产生数据源没有切换的问题
4.为了使@DS起作用,必须替换数据库连接,也就是改变事务的传播机制,产生新的事务,获取新的数据库连接
5.所以方法上除了加@Transactional外,还需要设置propagation = Propagation.REQUIRES_NEW

注意:需要说明的是,属性Propagation结合@transaction注解使用。

事务传播机制—七种枚举可分三类:

1.支持当前事务的事务传播机制

  1.REQUIRED----无事务新建事务,有则加入这个事务
  2.SUPPORTS----支持当前事务,无事务就以非事务方式执行;注意,如有外部存在事务,加入事务,无则省略
  3.MANDATORY----支持当前事务,当前不存在事务,则抛出异常  	

2.不支持当前事务的事务传播机制

  1.REQUIRES_NEW----存在事务则挂起,重新创建新事物执行,直至事务提交或回滚,原来的事务才会恢复执行
  2.NOT_SUPPORTED---以非事务方式执行,如操作在一个事务中,事务挂起,操作完成后才会恢复事务的执行
  3.NEVER----以非事务方式执行,存在事务则抛出异常

3.嵌套事务机制

  1.NESTED----表示当前有一个事务正在运行,则这方法应该运行在嵌套事务中,被嵌套的事务可独立于提交或回滚。没有事务,则按照REQUIRED机制实行。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值