Mysql数据库更新操作导致死锁问题

本文记录了一起因批量更新操作导致的MySQL数据库死锁问题。项目基于Spring,使用InnoDB引擎。分析发现,手动和自动盘点业务的更新语句导致了表级锁,引发死锁。通过调整SQL语句,将批量更新改为单条更新,避免了锁表,从而解决了死锁问题。建议在高并发场景下,使用单条更新语句并确保WHERE子句利用索引以减少锁竞争。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近维护项目发现的一个有意思的问题,写篇文章记录一下。
项目的问题是数据库发生了死锁,在盘查的所有的业务代码后我认为是“单条”批量update语句需要锁表而引发的问题

项目是基于spring的webservice,采用mysql数据库innodb引擎,问题涉及的主要业务如下:
业务1:系统会定期盘点数据(以下称为自动盘点),盘点中一个必要的数据不是存放在本地,需要通过http请求远程服务器,所以会导致服务层的一个方法运行缓慢(大约需要5小时)
业务2:管理员可以对某些数据进行手动盘点,手动盘点也需要通过http请求远程服务器,但是由于手动盘点数据一般较少,所以手动盘点只需要执行数分钟。

我查看了一下spring的配置,发现原先开发的时候为了省事,直接采用spring自动管理事务方式,代理了service层的所有方法。我们知道update事务需要获取mysql的写锁,由于数据库引擎采用的是innodb,在有索引的情况下会使用行锁,这样只要更新完立即释放锁,理论上就可以避免死锁了。
在咨询了老员工,发现某条数据更新失败不会影响整体的数据完整性,于是我将自动盘点更改为手动事务,获取到数据之后立即写入数据库,但是还是会与手动盘点冲突,问题还是存在。我查看了一下mybatis的更新语句,发现手动盘点有一条这样的语句:

update `A` set 省略 where id in(select id from `B`
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值