项目场景:
搭配使用 - @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.支持当前事务的事务传播机制
扫描二维码关注公众号,回复:
17436095 查看本文章

1.REQUIRED----无事务新建事务,有则加入这个事务 2.SUPPORTS----支持当前事务,无事务就以非事务方式执行;注意,如有外部存在事务,加入事务,无则省略 3.MANDATORY----支持当前事务,当前不存在事务,则抛出异常
2.不支持当前事务的事务传播机制
1.REQUIRES_NEW----存在事务则挂起,重新创建新事物执行,直至事务提交或回滚,原来的事务才会恢复执行 2.NOT_SUPPORTED---以非事务方式执行,如操作在一个事务中,事务挂起,操作完成后才会恢复事务的执行 3.NEVER----以非事务方式执行,存在事务则抛出异常
3.嵌套事务机制
1.NESTED----表示当前有一个事务正在运行,则这方法应该运行在嵌套事务中,被嵌套的事务可独立于提交或回滚。没有事务,则按照REQUIRED机制实行。