前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >线上报“Lock wait timeout exceeded; try restarting transaction”,怎么办?

线上报“Lock wait timeout exceeded; try restarting transaction”,怎么办?

作者头像
烟雨平生
发布2023-03-07 13:52:08
3910
发布2023-03-07 13:52:08
举报
文章被收录于专栏:数字化之路
线上报错了:
代码语言:javascript
复制
Caused by: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
分析
  1. 排查数据库。MySQL在报错期间的各项指标无异常。排除
  2. 结合代码分析日志。报错接口更新数据库的api,另外一个服务也在调用,且是报错接口的前置服务。

如果下图所示:

这个前置服务执行时间较长,平均耗时10min+

由于这个任务在入口方法上使用了事务,如果服务内的所有原子任务不全部执行完成,期间所有的变更就都不会被提交到MySQL,即服务未结束前,所有被update的记录,在这10min内,其它任何试图更新这些记录的操作都会出现更新失败。

猜测应该就是这个数据库大事务造成的

复现:设计case

case:

  1. 模拟一个耗时的服务。
  • 这个服务要更新某条记录
  • 这个服务要有数据库事务
  • 这个服务要耗时
  • 在服务全部完成后,再提交事务

需要步骤1.中的服务未结束前,也更新同一条记录。

期望:在步骤2执行时报错:

代码语言:javascript
复制
Lock wait timeout exceeded; try restarting transaction
复现:执行

code:

1.触发要执行5分钟的服务:要先执行,且更新id=1的记录

  1. 在/tasks/5min执行未结束前,触发/tasks/1服务:更新id=1的记录

同样的报错出现了!!!

Fix :在更新同一条记录时,要尽可能快速提交变更到数据库

就本次的情况,将耗时任务的事务去掉了。 当前场景,虽然一个原子任务会有两次更新数据库,但都是同一条记录按id进行更新。这种情况出错的可能性很小。 即使出错,再触发一次就可以解决,即具备自愈性,系统自身能保证最终一致。

小结
  1. 更新操作中,非必要,不要使用事务。

一定要使用事务的场景:有多个操作,如果不同时提交变更,最终数据肯定会不一致。即没有人工干涉,不可能自愈。

  1. 如果一定要使用事务,粒度越小越好。

事务期间,会占用一个数据库连接,影响服务的并发。 事务不提交,非当前事务的服务都看不到已经做出的变更。 即同一个时间点,同一条数据在某个时间点有多个状态同时存在,是引发数据不一致的"坏味道"

一个事务使用不当的“坏味道”:

”犯错不是最可怕的,蠢才是” 所谓蠢,上面一春,下面两个虫。春暖花开天气回暖,虫子们都开始活动,很多虫在一起动,又不能像人一样有秩序。看起来就很乱,所以乱动为之蠢。形容一个人胡乱的操作可以谓之蠢。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-07-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 的数字化之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 分析
  • 复现:设计case
  • 复现:执行
  • Fix :在更新同一条记录时,要尽可能快速提交变更到数据库
  • 小结
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档