mysql数据库锁超时问题
一.现象
最近生产环境收到告警,异常堆栈信息如下
【异常日志】
### Error updating database. Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
二.问题
某表锁等待超时。那么什么时候会产生锁等待
事务竞争同一行锁
1 下面我们做个实验,新建一张表student
CREATE TABLE `student` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL COMMENT '姓名',
`age` int DEFAULT NULL COMMENT '年龄',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3 COMMENT='学生';
2 插入一条数据 
3 我们手动开始事务,对id=1的表进行更新

4 此时事务并未提交。我们开启另一个console窗口

5 经过一段时间后,报错Lock wait timeout。

结论
-
排他锁冲突
当多个事务同时请求同一行记录的排他锁(如UPDATE、DELETE、SELECT ... FOR UPDATE),且前一个事务未提交或回滚时,后续事务会进入等待状态。
示例:事务 A 更新某行未提交,事务 B 尝试更新同一行时需等待锁释放
由此结论可推断当springboot项目中多个线程运行同一个方法时,并对数据库某张表进行UPDATE、DELETE等操作时,前一个事务尚未提交,后一个线程的事务就会造成锁等待,若超过最大锁等待时间,则mysql会抛出Lock wait timeout异常
如何解决Lock wait timeout异常
-
避免长时间不提交事务
若事务长时间未提交或回滚(如大事务、意外中断未关闭连接),持有的锁未被释放,后续操作相同记录的事务将进入锁等待。
避免长时间不提交事务,如批处理操作。可将事务拆分成小事务
2. 尽量避免在事务中进行网络请求,因网络有波动,可能会造成方法执行较长时间
3. 能用行锁就不用表锁
当未对条件字段建立有效索引时,行锁可能升级为表锁,导致更多事务因表级锁竞争进入等待。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)