本文涉及的产品
对象存储 OSS,20GB 3个月
云备份 Cloud Backup,100GB 3个月
对象存储 OSS,恶意文件检测 1000次 1年
简介: MySQL使用行级锁时,并非直接锁定记录,而是锁定涉及的索引。对于表`user_item`,更新语句先锁定非主键索引`idx_1`,再锁定主键索引。若两条更新语句分别按不同顺序锁定这两个索引,可能导致互相等待对方释放锁,引发死锁。解决方案包括先查询待更新记录的主键,再按主键更新,确保一致的锁定顺序。

行级锁在使用的时候并不是直接锁掉这行记录,而是锁索引
如果一条sql用到了主键索引(mysql主键自带索引),mysql会锁住主键索引;
如果一条sql操作了非主键索引,mysql会先锁住非主键索引,再锁定主键索引.
以下问题的总结:同一个事务,两次修改同一个表,第一个sql先锁A索引再锁B索引,第二个sql先锁B索引再锁A索引,而这两个SQL的数据应该是有重叠
CREATE TABLE user_item (
id BIGINT(20) NOT NULL,
user_id BIGINT(20) NOT NULL,
item_id BIGINT(20) NOT NULL,
status TINYINT(4) NOT NULL,
PRIMARY KEY (id),
KEY idx_1 (user_id,item_id,status)
) ENGINE=INNODB DEFAULT CHARSET=utf-8
update user_item set status=1 where user_id=? and item_id=?
1.由于用到了非主键索引,首先需要获取idx_1上的行级锁
2.紧接着根据主键进行更新,所以需要获取主键上的行级锁;
3.更新完毕后,提交,并释放所有锁。
//如果在步骤1和2之间突然插入一条语句:
update user_item .....where id=? and user_id=?
//这条语句会先锁住主键索引,然后锁住idx_1。
//蛋疼的情况出现了,一条语句获取了idx_1上的锁,等待主键索引上的锁;
//另一条语句获取了主键上的锁,等待idx_1上的锁,这样就出现了死锁。
解决方案
//1.先获取需要更新的记录的主键
select id from user_item where user_id=? and item_id=?
//2. 逐条更新
...

目录
相关文章
|
2月前
|
存储 关系型数据库 MySQL
MySQL数据库锁:共享锁和独占锁
本文详细介绍了`InnoDB`存储引擎中的两种行级别锁:共享锁(S锁)与排他锁(X锁)。通过具体示例展示了这两种锁的工作机制及其在`InnoDB`与`MyISAM`引擎中的表现差异。文章还提供了锁的兼容性矩阵,帮助读者更好地理解锁之间的互斥关系。最后总结了两种锁的特点及适用场景。适合希望深入了解`MySQL`并发控制机制的读者阅读。
96 1
|
4月前
|
SQL 关系型数据库 MySQL
临键锁引发的死锁
【8月更文挑战第4天】
44 0
临键锁引发的死锁
|
4月前
|
数据库 SQL
间隙锁+临键锁
【8月更文挑战第1天】
51 0
|
Linux API C++
锁、避免死锁等相关
锁、避免死锁等相关
71 0
《锁》有那些?
锁是计算机科学中用于控制对共享资源的访问的一种同步机制。不同种类的锁适用于不同的场景和需求。下面是一些常见的锁的种类及其详细介绍:
83 1
|
存储 算法 安全
辛辛苦苦的劳动成果,如何上把锁?
辛辛苦苦的劳动成果,如何上把锁?
|
数据可视化 Java
lock锁和死锁
lock锁和死锁
共享锁(读锁)和排他锁(写锁)
共享锁(读锁)和排他锁(写锁)
206 0
|
数据库
关于锁的基本概念理解
112 0
|
PHP
并发锁(二):共享锁和独占锁
并发锁(二):共享锁和独占锁
219 0
并发锁(二):共享锁和独占锁