MySql数据库死锁deadlock

本文详细探讨了Mysql InnoDB数据库在并发操作中出现死锁问题的原因,通过具体案例分析了死锁的发生过程及解决策略。

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

 

今天在项目性能测试中遇到个Mysql的DeadLock的问题。

后来根据数据库日子查找原因,大概模拟一下发生的情形。

 

数据库用的innoDB。

InnoDB行锁是通过给索引上的索引项加锁来实现的,InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!

下面例子中id是主键,操作都走索引,锁都是row lock。

 
table中数据
 

 

用2个线程做如下操作,将发生死锁现象,且1个线程执行成功,另一个线程失败。

 

最终结果:第一条数据被改变,第3条数据不变。

 

MySql的InnoDB,\加了事务的select语句索引的记录,会加S锁, insert,delete,update会加X锁。

设定左边为线程1,右边为线程2

线程1在id=1的一行记录上加了S锁, 当线程2要update操作这行记录时,要在记录上加X锁, 此时需要等待线程1释放id=1记录上的S锁。

线程2在id=3的一行记录上加了S锁, 当线程1要update操作这行记录时,要在记录上加X锁, 此时需要等待线程2释放id=3记录上的S锁。

彼此互相等待,然后就死锁了。

Mysql释放死锁的机制,看锁定的记录数,一般会允许锁定记录多的事务执行通过, 而锁定记录少的事物回滚。范围同等时应该是按X锁请求的先后了。

 

补充说明: InnoDB 如果where后面的条件字段没有索引,则加锁时是会锁表。走索引只会锁查询或操作的记录。InnoDB事务中的查询条件需要小心了

互斥

S

X

S

X

 

先写这么多。

### 解决 MySQL 数据库死锁问题 #### 死锁现象描述 在并发系统中,特别是数据库操作时,当两个或更多事务相互持有并等待对方释放所需资源的情况称为死锁。这种情况下,每个事务都无限期地等待另一个事务完成,从而形成僵局。对于MySQL而言,典型的错误提示为 “Deadlock found when trying to get lock...”[^2]。 #### 查看当前活动的事务及其锁定状态 为了更好地理解哪些查询参与到了死锁之中,可以利用 `information_schema` 下面的一些视图来进行分析: ```sql SELECT * FROM information_schema.innodb_trx\G; ``` 这条命令能够展示所有正在运行中的InnoDB事务详情,帮助识别可能涉及死锁的操作[^3]。 进一步地,通过联合查询 `INNODB_LOCKS` 和 `INNODB_LOCK_WAITS` 表可以获得更详细的关于具体哪个事务阻塞了其他事务的信息: ```sql SELECT r.trx_id waiting_trx_id, r.trx_mysql_thread_id waiting_thread, r.trx_query waiting_query, b.trx_id blocking_trx_id, b.trx_mysql_thread_id blocking_thread, b.trx_query blocking_query FROM information_schema.innodb_lock_waits w INNER JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_trx_id INNER JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_trx_id; ``` 上述SQL语句有助于追踪到具体的死锁链路以及相关联的SQL执行情况[^4]。 #### 预防措施与解决方案 针对由单个事务内多次跨表访问引发的潜在死锁风险,建议优化应用程序逻辑设计,尽可能减少复杂度高的嵌套查询次数;另外还可以考虑调整索引结构以提高数据检索效率,进而缩短加锁时间窗口[^1]。 如果业务允许的话,适当放宽事务隔离级别也是一种有效的策略,比如从可重复读(Repeatable Read)降级至读已提交(Read Committed),这可以在一定程度上缓解因高并发带来的争用压力。 最后值得注的是,在某些特殊场景下即使采取预防手段也无法完全杜绝死锁的发生,此时应确保应用层具备良好的异常处理机制,能够在检测到死锁后自动重试失败交易直至成功为止。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值