问题描述
在使用Spring 事务的时候,加上了timeout的限制,@Transactional(timeout = 10),发现事务不会因为超时回滚。
功能描述
所谓事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。在 TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒。
默认设置为底层事务系统的超时值,如果底层数据库事务系统没有设置超时值,那么就是none,没有超时限制。
问题原因
Spring事务超时 = 事务开始时到最后一个Statement创建时时间 + 最后一个Statement的执行时超时时间(即其queryTimeout)。所以在在执行Statement之外的超时无法进行事务回滚。
解决办法
举个例子
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14@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里面的
最后
以上就是虚幻鸭子最近收集整理的关于Spring事务采坑 —— timeout的全部内容,更多相关Spring事务采坑内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复