mysql在update,非主键索引更新引起死锁问题
mysql在update,非主键索引更新引起死锁
1.mysql存储引擎
Innodb:支持事务,更新时采用行级锁,并发性高
MyISAM:不支持事务,更新时表锁,并发性差
因此使用Innodb才会发生死锁,从mysql5.6开始默认引擎Innodb
2.update更新过程
行级锁并不是直接锁记录,而是锁索引,如果一条SQL语句用到了主键索引,mysql会锁住主键索引;如果一条语句操作了非主键索引,mysql会先锁住非主键索引,再锁定主键索引。
反之:
- 如果操作用到了主键索引会先在主键索引上加锁,然后在其他索引上加锁。
- 如果没有用到索引,则进行全表扫描,锁表。
当where条件为非主键索引,执行update时,会经过一下步骤:
1)先获取非主键索引的行级锁;
2)由数据库基本原理可知,where条件为非主键索引时,会发生回表查询,进而再获得主键索引的行级锁;
3)更新完毕,进行事务提交。
根据上述步骤可知,对于非主键索引的update操作,其加锁过程并非原子操作,而且是分别需要获取不同索引的行级锁,可能会产生死锁:
假如:
一条update语句用到主键索引和非主键索引,则获取锁的顺序是先获取主键索引,再获取非主键索引;
而同时,另一条update语句只用到非主键索引,则获取锁的顺序是先获取非主键索引,再获取主键索引,二者正好发生在步骤 1)和 2)中间,则会造成锁。
3.解决方案
where条件加主键索引
先上锁查询查出来,在根据主键更新
逐条更新
行级锁是锁索引:
由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的
mysql批量update死锁
项目使用了多线程,同时调用service中的update方法更新数据,之前由于在update方法上加了synchronized做了线程同步,没有出现mysql update死锁的问题。
但是由于update更新耗时比较长,synchronized锁住对象,导致调用service中的其他方法阻塞,效率地下,于是优化synchronized,移到方法内部的同步代码段,然后虽然效率提高了,但是mysql总是出现死锁的bug:
Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found
when trying to get lock; try restarting transaction;
发生原因
T1:begin tran select * from table lock in share mode update table set column1='hello'
T2:begin tran select * from table lock in share mode update table set column1='world'
假设 T1 和 T2 同时达到 select,T1 对 table 加共享锁,T2 也对 table 加共享锁,当 T1 的 select 执行完,准备执行 update 时,根据锁机制,T1 的共享锁需要升级到排他锁才能执行接下来的 update.在升级排他锁前,必须等 table 上的其它共享锁(T2)释放,同理,T2 也在等 T1 的共享锁释放。于是死锁产生了。
因此,当sql发出一个update请求之后,数据库会对表中的每条记录加上共享锁。
然后数据库会根据where条件,将符合条件的记录转换为排他锁(mysql innodb默认对索引加锁),我们的多个线程update时,就出现了上面的情况,发生了死锁。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
Mysql彻底解决中文乱码问题的方案(Illegal mix of collations for operation)
mysql数据库和中文支持很不友好,经常见到“Illegal mix of collations for operation”错误,该如何解决呢?下面小编给大家带来了mysql数据库中涉及到哪些字符集及彻底解决中文乱码的解决方案,非常不错,一起看看吧2016-08-08
You have an error in your SQL&
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version2023-02-02
Mysql连接本地报错:1130-host ... is not allowed to connect t
这篇文章主要给大家介绍了关于Mysql连接本地报错:1130-host ... is not allowed to connect to this MySQL server的解决方法,文中通过图文介绍的非常详细,需要的朋友可以参考下2023-03-03
mysql注入之长字符截断,orderby注入,HTTP分割注入,limit注入方式
这篇文章主要介绍了mysql注入之长字符截断,orderby注入,HTTP分割注入,limit注入方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2023-11-11
MySql,MVCC实现及其机制,快照读在RC,RR下的区别说明
这篇文章主要介绍了MySql,MVCC实现及其机制,快照读在RC,RR下的区别说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2024-04-04
windows 64位下MySQL 8.0.15安装教程图文详解
本文通过图文并茂的形式给大家介绍了MySQL 8.0.15安装教程(windows 64位),非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下2019-04-04


最新评论