理解本篇文章需要的知识储备:
我们把事务传播过程中的外层称为调用者,内层称为被调用者
物理事务:一次connection(相当于mybatis的一次sqlsession)的开启和关闭,其间的所有数据库操作
逻辑事务:被@Transactional注解修饰的操作,具体根据传播行为来判断是否是逻辑事务
被调用者中(调用者已经存在事务),只有PROPAGATION_REQUIRES_NEW传播行为开启了一个新的物理事务,其他传播行为都是逻辑事务
下面通过代码分析
Propagation.REQUIRED事务传播方式
调用者代码:
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public void requestTransactional() {
userService.addUser(6, "user6");
userServiceTransactionStateInvoked.requestTransactional();
}
被调用者代码:
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public void requestTransactional() {
userService.addUser(6, "user6");
}
调用者和被调用者的事务传播行为都是:Propagation.REQUIRED
执行代码日志如下:
我们一步步分析两次插入数据代码执行流程:
执行过程中两次插入数据属于两个不同的逻辑事务,但是他们同属于一个物理事务(因为sqlsession和connection)始终是同一个。
一步步分析下来对逻辑事务和物理事务将会有一个直观的认识。
Propagation.REQUIRES_NEW事务传播方式
调用者代码:
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES\_NEW)
public void requiresNewTransactional() {
userService.addUser(6, "user6");
userServiceTransactionStateInvoked.requiresNewTransactional();
userService.addUser(6, "user6");
}
被调用者代码:
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES\_NEW)
public void requiresNewTransactional() {
userService.addUser(7, "user7");
}
执行代码日志如下:
分析3次插入数据代码执行流程的关键步骤:
最终执行结果:第一次和第三次数据插入失败,只有第二次插入数据成功。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。