@Transactional的传播属性REQUIRES_NEW深入理解

前提

spring boot项目;sql server;druid连接池;

结论

requires_new传播属性,会新建一个事务(即新连接),挂起旧事务的意思,其实是因为用到了ThreadLocal来保存DB链接信息,需要将ThreadLocal处理成当前事务的信息才行。

因此两个事务 也是有资源的竞争关系,下面举个例子来说明,外层事务A REQUIRED, 会插入一条新记录到test_a; 内层事务B会查询 test_a的所有记录,因为sql server默认读已提交 隔离级别,故需要等到A提交后,才能查询到,但事务A已经被挂起,需要B执行完才能继续运行。
即出现这样的情况,事务A需要B执行完才能继续运行, 而事务B等着事务A提交才能继续运行,故死锁了!!!

假如我们把事务B,即BService的方法isolation = Isolation.READ_UNCOMMITTED隔离级别设置低一些,就不会产生死锁了!

研究的代码例子

先做个用例, 在springboot项目里面

@RestController
@RequestMapping(value = "/test/transational/requiresnew", produces = "application/json;charset=UTF-8")
public class TransactionalRequiresNewController {
    @Autowired
    private AService aService;

    /**
     * 外层required,内层requires_new
     * 外层插入新记录key1;
     * 执行内层,selectAll,插入新纪录key2;
     * 外层两次插入新纪录key3,触发报错回滚;
     *
     * 期望:
     * 1.会陷入死循环,因为外层的插入未提交;内层selectAll一直在等待;
     * @return
     */
    @GetMapping("/deadLock")
    public String requiresNewDeadLock() {
        try {
            String s = aService.requiresNewDeadLock();
            System.out.println("requiresNewDeadLock: " + s);
            return s;
        } catch (Exception e) {
            e.printStackTrace();
            return "error";
        }
    }
}
// AService
    @Autowired
    private BService bService;
@Transactional(propagation = Propagation.REQUIRED)
    @Override
    public String requiresNewDeadLock() {
        keywordDao.insertToA("requiresNewDeadLock1");
        return bService.requiresNewDeadLock();
    }

// BService
@Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public String requiresNewDeadLock() {
       // 会死锁在这里。前一个事务A插入新数据,但未提交,sql server默认是读已提交,故这里requires_new新建的事务B一直在等待;
        List<String> strings = keywordDao.selectAllKeywordInA();
        return "ok";
    }
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值