Spring事务采坑 —— timeout

问题描述

在使用Spring 事务的时候,加上了timeout的限制,@Transactional(timeout = 10),发现事务不会因为超时回滚。

功能描述

所谓事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。在 TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒。
默认设置为底层事务系统的超时值,如果底层数据库事务系统没有设置超时值,那么就是none,没有超时限制。

问题原因

Spring事务超时 = 事务开始时到最后一个Statement创建时时间 + 最后一个Statement的执行时超时时间(即其queryTimeout)。所以在在执行Statement之外的超时无法进行事务回滚。

解决办法

举个例子

@Transactional(timeout = 2, rollbackFor = Exception.class,isolation = Isolation.DEFAULT)
  public void createOrder(Integer userId, Integer goodsId, Integer amount) throws Exception {
      //减少库存
      int result = goodsDao.updateGoodsStock(goodsId, amount);
      if (result != 1) {
          throw new Exception("创建订单失败");
      }
      //制造异常
//        int i = 1/0;
      //插入订单
      orderDao.insert(userId, goodsId, amount);
      Thread.sleep(3000);
  }

在段代码中,如果把Thread.sleep(3000);放到最后,并不会回滚。所以开发的时候要特别注意。如果真的有特别重要的操作(在最后一个Statement之后),我现在的解决办法是,
* 尽量在执行Statement的中间
* 在操作的最后再加一个无关的轻量Statement操作

原理

有时间在看,肯定是Spring AOP里面的

猜你喜欢

转载自blog.csdn.net/qq_18860653/article/details/79907984
今日推荐