您当前的位置: 首页 > 

梁云亮

暂无认证

  • 1浏览

    0关注

    1211博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

@Transactional失效场景汇总

梁云亮 发布时间:2020-06-17 14:03:59 ,浏览量:1

@Transactional失效场景汇总
  1. 数据库引擎不支持事务
  2. 异常被catch捕获导致@Transactional失效
  3. 如果Transactional注解应用在非public 修饰的方法上,Transactional将会失效。
  4. @Transactional 注解属性 propagation 设置错误,以下三种 propagation,事务将不会发生回滚。
  5. TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
  6. TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
  7. TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
  8. @Transactional 注解属性 rollbackFor 设置错误 Spring默认在抛出了未检查unchecked异常(继承自 RuntimeException 的异常)或者 Error时才回滚事务;其他异常不会触发回滚事务。如果在事务中抛出其他类型的异常,但却期望 Spring 能够回滚事务,就需要指定 rollbackFor属性。
  9. 同一个类中方法调用,导致@Transactional失效
示例: Service层代码
@Service
public class DeptServiceImpl implements DeptService {
    @Resource
    private DeptMapper deptMapper;
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public int deleteByDeptno(Integer deptno) {
        deptMapper.deleteByPrimaryKey(deptno);
        throw new RuntimeException();//模拟出错
    }
    @Override
    public int save(Dept record) {
        int res1 = deptMapper.insert(record);//插入
        int res2 = deleteByDeptno(83); //没有使用代理,事务传播不会生效
        return res1 + res2; //模拟出错
    }
}
测试代码
@SpringBootTest
class DeptServiceImplTest {
    @Resource
    private DeptService deptService;
    @Test
    void insert() {
        Dept dept = Dept.builder()
                .dname("bb")
                .loc("bbbbbbbbb").build();
        int insert = deptService.insert(dept);
        System.out.println(insert);
    }
}

尽管deleteByDeptno()方法开启了事务,但save()方法中调用deleteByDeptno()方法进没有使用代理,所以事务传播不会生效,即出错事务不会回滚。

Service层代码
@Service
public class DeptServiceImpl implements DeptService {
    @Resource
    private DeptMapper deptMapper;
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public int deleteByPrimaryKey(Integer deptno) {
        deptMapper.deleteByPrimaryKey(deptno);
        throw new RuntimeException();//模拟出错
    }
    @Resource
    private DeptService deptService;
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public int insert(Dept record) {
        int res1 = deptMapper.insert(record);//插入
        int res2 = deptService.deleteByPrimaryKey(83);//使用了代理,事务会回滚
        //System.out.println(3 / 0);
        return res1 + res2; //模拟出错
    }
}

deleteByDeptno()方法开启了事务,save()方法中调用deleteByDeptno()方法进使用了代理,所以事务传播会生效,即出错事务会回滚。

关注
打赏
1665409997
查看更多评论
立即登录/注册

微信扫码登录

0.0903s