Spring事务采坑 —— timeout

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_18860653/article/details/79907984
问题描述
在使用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里面的



posted @   LZ太热  阅读(2770)  评论(1编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示