zoukankan      html  css  js  c++  java
  • @Transaction使用注意事项

    准备工作:

    创建两张mysql表,id设置为自增。test1表有id和name字段,test2有id和name字段(且name字段不为空)

    测试一:

    controller层
    @GetMapping("/test")
    public Result test(String userName) {
        return service.test(userName);
    }

    serviceImpl层

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result test(String userName) {
        testMapper.saveTest1("userName1");--没有回滚
        try {
            saveTest2(userName);
        } catch (Exception e) {
            log.warn("test报错{}", e.getMessage());
        }
        return Result.succeed("成功");
    }
    
    @Transactional(rollbackFor = Exception.class)
    public void saveTest2(String userName) {
        testMapper.saveTest1("userName2");--没有回滚
        testMapper.saveTest2(userName);--没有回滚
    }

    mapper层

    @Insert("insert into test1(name) values(#{userName})")
    void saveTest1(String userName);
    
    @Insert("insert into test2(name) values(#{userName})")
    void saveTest2(String userName);

    调用/test接口,不传参数,最终结果:

    test1表里有两条数据,test2表里没有数据,也就是事务没有回滚。

    test1表数据如下:

    测试二:

    controller层
    @GetMapping("/test1")
    public Result test1(String userName) {
        return service.test1(userName);
    }

    serviceImpl层

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result test1(String userName) {
        testMapper.saveTest1("userName1");
        try {
            otherServiceImpl.saveTest2(userName);
        } catch (Exception e) {
            log.warn("test报错{}", e.getMessage());
        }
        return Result.succeed("成功");
    }
    

    新建一个otherServiceImpl类,把测试一的saveTest2方法直接挪过来

    @Transactional(rollbackFor = Exception.class)
    public void saveTest2(String userName) {
        testMapper.saveTest1("userName2");
        testMapper.saveTest2(userName);
    }

    mapper层

    @Insert("insert into test1(name) values(#{userName})")
    void saveTest1(String userName);
    
    @Insert("insert into test2(name) values(#{userName})")
    void saveTest2(String userName);

    调用/test1接口,不传参数,最终结果:

    test1和test2表里都没有数据,也就是saveTest2方法被移到另一个service类的时候,事务回滚了。

     测试一和测试二得出结论:

    在同一个类中,一个方法调用另一个带@Transaction注解的方法时,方法上的@Transaction注解不会生效。

    解决这个问题,有一个简单的办法,就是新建一个类,将第二个方法移到新写的类里,此时@Transaction注解就可以生效了。

    测试三:

    controller层
    @GetMapping("/test2")
    public Result test2(String userName) {
        return service.test2(userName);
    }

    serviceImpl层

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result test2(String userName) {
        testMapper.saveTest1("userName1");
        try {
            saveTest2(userName);
        } catch (Exception e) {
            log.warn("test报错{}", e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return Result.succeed("成功");
    }
    
    @Transactional(rollbackFor = Exception.class)
    public void saveTest2(String userName) {
        testMapper.saveTest1("userName2");
        testMapper.saveTest2(userName);
    }

    mapper层

    @Insert("insert into test1(name) values(#{userName})")
    void saveTest1(String userName);
    
    @Insert("insert into test2(name) values(#{userName})")
    void saveTest2(String userName);

    调用/test3接口,不传参数,最终结果:

    test1和test2表里都没有数据。

    即:在同一个类中,一个方法调用另一个带@Transaction注解的方法时,加上“TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();”,方法上的@Transaction注解就会生效。

  • 相关阅读:
    Ural_1018. Binary Apple Tree(树形DP)
    2011 Asia Shanghai Regional Contest Problem A
    Ural_1012. Kbased Numbers. Version 2(dp)
    HDU_1524 A Chess Game (sg函数)
    HDU_1760 A New Tetris Game(dfs + 博弈)
    POJ_2023 Choose Your Own Adventure(DFS)
    POJ_3267 The Cow Lexicon(DP)
    Qt 的QString类的使用
    用QFileSystemModel和Listview做的简易图片浏览
    Qt 对文件的操作
  • 原文地址:https://www.cnblogs.com/supiaopiao/p/15403916.html
Copyright © 2011-2022 走看看