mysql两个事务执行相同语句导致Deadlock

本文详细分析了在服务器通信过程中因事务操作导致的DeadLock问题。通过对具体场景的描述,阐述了问题产生的原因及三种解决方案。

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

    服务器通信时,SQL语句发生了DeadLock问题,使用事务操作包含相同的update语句导致的deadlock,整了很长一段时间,记录一下。

前提:1:事务A和事务B,在不同线程中,轮询调用使用函数封装的update语句

         2:表结构中包含两个字段table_name、user_id,并且将这两个字段设定为唯一索引。

发生错误现象:通过日志以及语句:SHOW ENGINE INNODB STATUS\G,查看发生发生DeadLock现象;

发生问题原因:1.线程A开启事务,并update某一个数据,由于table_name、user_id两字段是唯一索引,因此会开启行级锁。

                       2.线程B开启事务,同时update这张表,并开启相应行级锁。

                        3.两个线程开启的事务中,都包含轮询操作。假定第一次线程A锁定行数1,线程B锁定行数2;接着第二次线程A锁定行数2,此时会出现等待,若同时现场线程B尝试更新行数1,则会发生死锁现象;如下两张图:

线程1(轮询语句写在begin和commit之间,线程1更新表raw_key_5后不进行commit,但此时线程2抢夺了资源,并更新了表raw_key_4,当线程2接下去操作raw_key_5时会出现等待,而当线程1再次拿到资源后更新表raw_key_4时就会报deadlock):

线程2:

解决方案:1.将事务执行范围缩小。

                2.删除相关唯一索引,将锁范围扩大至表级锁。

                3.修改更新语句,将查询条件扩大化,将锁范围扩大至表级锁。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值