wangwang
wangwang
文章32
标签32
分类5
事务注解@Transactional踩坑

事务注解@Transactional踩坑

常见问题整理

1.当标记了@Transactional注解的方法中出现异常时,如果该异常未传播到该方法外,则事务不会回滚,反之,只有异常传播到该方法外,事务才会回滚

错误示例:

// 异常被try-catch了
@Override
@Transactional
public Result firstFunctionAboutException() {
    try{
        log.info("减库存开始");
        goodsStockMapper.updateStock();
        if(1 == 1) throw new RuntimeException();
        return Result.ok();
    }catch (Exception e){
        log.info("减库存失败!" + e.getMessage());
        return Result.server_error().Message("减库存失败!" + e.getMessage());
    }
}

正确示例:

@Override
@Transactional
public void secondFunctionAboutException() {
    log.info("减库存开始");
    goodsStockMapper.updateStock();
    if(1 == 1) throw new RuntimeException();
}

2.默认情况下,如果我们抛出的不是RuntimeException时,事务不会回滚,需要手动抛出RuntimeException异常或者修改@Transactional注解默认配置

错误示例

@Override
@Transactional
public void thirdFunctionAboutException() throws Exception {
    log.info("减库存开始");
    goodsStockMapper.updateStock();
    if(1 == 1) throw new Exception();
}

正确示例

// 抛出RuntimeException
@Override
@Transactional
public void thirdFunctionAboutException1(){
    try{
        log.info("减库存开始");
        goodsStockMapper.updateStock();
        if(1 == 1) throw new Exception();
    }catch (Exception e){
        log.info("出现异常"+e.getMessage());
        throw new RuntimeException("手动抛出RuntimeException");
    }
}

// 指定回滚异常
@Override
@Transactional(rollbackFor = Exception.class)
public void thirdFunctionAboutException2() throws Exception {
    log.info("减库存开始");
    goodsStockMapper.updateStock();
    if(1 == 1) throw new Exception();
}

3.被注解的方法必须是public的,且必须由注入bean来直接调用才能事务回滚

错误示例

//在普通方法中调用事务方法
@Override
public void privateFunctionCaller (){
    privateCallee();
}

// 使用private修饰
@Transactional
private void privateCallee(){
    goodsStockMapper.updateStock();
    throw new RuntimeException();
}

正确示例

@Override
@Transactional
public void publicCallee(){
    goodsStockMapper.updateStock();
    throw new RuntimeException();
}

// 使用自身service调用,或者将两个方法放置于不同的service
@Autowired
private GoodsStockService self;

@Override
public void aopSelfCaller (){
    self.publicCallee();
}

先记录到这,后续学习再补充!!!!

本文作者:wangwang
本文链接:https://www.wangwangit.com/%E4%BA%8B%E5%8A%A1%E6%B3%A8%E8%A7%A3Transactional/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可