Transaction事务

UserController新增如下代码:

@GetMapping("save1")

public String save1(){
    User user = new User();
    user.setDptId(1L);
    user.setName("a");
    user.setAge(18L);
    user.setEmail("[email protected]");
    user.setHeadImg("headImg1");

    this.userJpa.save(user);
    //模拟发生了异常
    System.out.println(1/0);
    return "ok";
}

使用postman请求

localhost:8080/user/save1

执行之后可以看到java后台报错了,postman前台也报出来错误,但是数据却保存进去了,数据新增了一条记录

关于Mysql事务,你必须知道的几个知识点!-LMLPHP

说明即使发生了异常,数据还是会保存进去数据库,那应该怎么办呢?试试在save1方法上加一个@Transactional的注解。

我们再执行一次。发现错误也报出来了,但是数据库并没有将新数据插入进去,最新的还是上一次的id为7的记录,那么 Transactional注解是干嘛的呢?

  1. 该注解是添加在实现类或者接口实现方法上,而不能放在接口
  2. 需要注意的是这个注解只对public方法生效
  1. 将UserController中的代码稍作修改,手动throw new Exception("test"),再执行下postman,发现事务提交了,并没有回滚。
  2. 接着我们将注解修改为@Transactional(rollbackFor = Exception.class),再执行postman,事务却回滚了,并没有提交,什么原因?
  3. spring的@Transactional注解可以很方便的开启事务,但是默认只在遇到运行时异常Error时才会回滚,非运行时异常不回滚,即Exception的子类中,除了RuntimeException及其子类,其他的类默认不回滚。
  4. 而rollbackFor属性可以解决这个问题,rollbackFor = Exception.class表示Exception及其子类的异常都会触发回滚,同时不影响Error的回滚。

新增LogService类

@Service

public class LogService {
    @Resource
    private UserJpa userJpa;

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void saveLog(){
        User user = new User();
        user.setDptId(1L);
        user.setName("log");
        user.setAge(18L);
        user.setEmail("[email protected]");
        user.setHeadImg("log");

        this.userJpa.save(user);
        System.out.println("log");
    }
}

新增UserService类:

@Service

public class UserService {
    @Resource
    private UserJpa userJpa;
    @Resource
    private LogService logService;

    @Transactional(rollbackFor = Exception.class)
    public void saveBiz() throws Exception {
        System.out.println("save2");
        User user = new User();
        user.setDptId(1L);
        user.setName("biz");
        user.setAge(18L);
        user.setEmail("[email protected]");
        user.setHeadImg("biz");

        this.userJpa.save(user);

        //模拟保存日志
        this.logService.saveLog();
        //模拟发生了异常
        throw new Exception("test1");
    }
}

UserController新增代码

@GetMapping("save2")

public String save2() throws Exception {
    //模拟业务操作
    this.userService.saveBiz();
    return "ok";
}

postman执行下,是不是只有log的那条记录插入进去了?biz的没有插入进去。

更多原创阅读:点击

06-28 21:33