栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

个人学习系列 - @Transactional失效的3种情况

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

个人学习系列 - @Transactional失效的3种情况

面试的时候遇到过这个问题,当时一脸懵逼。现在记录一下。。。

@Transactional失效场景 1. 在类内部调用调用类内部@Transactional标注的方法 1.1 定义一个错误的@Transactional标注实现,设置一个内部调用
@Service
public class UserServiceImpl extends ServiceImpl implements IUserService {

    @Resource
    UserMapper userMapper;

    @Override
    public void oneTest() {
        oneTestNoPublic();
    }

    @Transactional(rollbackFor = Exception.class)
    public void oneTestNoPublic(){
        // 插入一条数据
        int num = userMapper.insert(new User("小红", "青岛市", 18));
        if (num > 0){
            // 插入后制造一个错误
            System.out.println(1 / 0);
        }
        // 再次插入一条数据
        userMapper.insert(new User("小强", "烟台市", 21));
    }
}
1.2 测试用例
@RestController
@RequestMapping("/transactional")
public class TransactionalTestController {

    @Resource
    IUserService userService;

    
    @GetMapping("/one")
    public void oneTest(){
        try {
            userService.oneTest();
        } catch (Exception e){
            e.printStackTrace();
        }
    }

}
1.3 运行后,控制台报错:

1.4 查看数据库,发现并没有回滚new User(“小红”, “青岛市”, 18)这条数据

调用一个方法在类内部调用内部被@Transactional标注的事务方法,运行结果是事务不会正常开启。userMapper.insert(new User(“小红”, “青岛市”, 18)) 操作没有进行回滚。

2. @Transactional注解标注方法修饰符为非public 2.1 新写一个TestServiceImpl,将@Transactional注解标注方法修饰符为非public
@Service
public class TestServiceImpl {

    @Resource
    UserMapper userMapper;

    @Transactional(rollbackFor = Exception.class)
    void twoTestNoPublic(){
        // 插入一条数据
        int num = userMapper.insert(new User("小红", "青岛市", 18));
        if (num > 0){
            // 插入后制造一个错误
            System.out.println(1 / 0);
        }
        // 再次插入一条数据
        userMapper.insert(new User("小强", "烟台市", 21));
    }
}
@Service
public class UserServiceImpl extends ServiceImpl implements IUserService {

    @Resource
    TwoTestServiceImpl twoTestService;

    @Override
    public void twoTest() {
        twoTestService.twoTestNoPublic();
    }
}
2.2 测试用例
@RestController
@RequestMapping("/transactional")
public class TransactionalTestController {

    @Resource
    IUserService userService;

    
    @GetMapping("/two")
    public void twoTest(){
        try {
            userService.twoTest();
        } catch (Exception e){
            e.printStackTrace();
        }
    }

}
2.3 运行后,控制台报错:

2.4 查看数据库,发现并没有回滚new User(“小红”, “青岛市”, 18)这条数据

以上的访问方式,导致事务没开启,因此在方法抛出异常时,userMapper.insert(new User(“小红”, “青岛市”, 18)) 操作没有进行回滚。如果oneTestNoPublic()方法改为public的话将会正常开启事务,userMapper.insert(new User(“小红”, “青岛市”, 18)) 将会进行回滚。

3. 事务方法内部捕捉了异常,且没有抛出新的异常 3.1 写一个内部捕捉异常,且不再抛出新的异常的方法
@Service
public class TestServiceImpl {

    @Resource
    UserMapper userMapper;

    @Transactional(rollbackFor = Exception.class)
    public void threeTestNoPublic(){
        // 插入一条数据
        int num = userMapper.insert(new User("小红", "青岛市", 18));
        if (num > 0){
            try {
                // 插入后制造一个错误
                System.out.println(1 / 0);
            } catch (Exception e) {
                e.printStackTrace();
                return;
            }
        }
        // 再次插入一条数据
        userMapper.insert(new User("小强", "烟台市", 21));
    }
}
3.2 测试用例
@RestController
@RequestMapping("/transactional")
public class TransactionalTestController {

    @Resource
    IUserService userService;

    
    @GetMapping("/three")
    public void threeTest(){
        try {
            userService.threeTest();
        } catch (Exception e){
            e.printStackTrace();
        }
    }

}
3.3 运行后,控制台报错:

3.4 查看数据库,发现并没有回滚new User(“小红”, “青岛市”, 18)这条数据

如果需要在catch里面回滚数据的话,就需要抛出新的异常或者在catch里面使用如下代码:TransactionAspectSupport.currentTransactionStatus().setRollbackonly();

好了,上面三种就是@Transactional注解不起作用,@Transactional注解失效的主要原因。

个人博客地址:

http://www.zhouzhaodong.xyz/

测试代码地址为:

https://gitee.com/zhouzhaodong/springboot/tree/master/transactional

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/602176.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号