MySQL 中 INSERT ... ON DUPLICATE KEY UPDATE 与 UPDATE ... WHERE id IN (...) 的执行和加锁顺序

结论: 1 . INSERT MySQL...ON DUPLICATE KEY UPDATE 首先解析语句,按 VALUES 顺序插入,检查唯一键冲突,然后将更新和键应用于每一行。
2 . UPDATE...WHERE id IN (...) 在索引数组中搜索更新,并将键应用于索引数组中的连续行。
3 . INSERT...ON DUPLICATE KEY UPDATE 按 VALUE 顺序运行,以确保一致的用户期望并提高效率。
4 .索引序列中UPDATE...WHERE id IN(...)以减少死锁,提高并发性能。
5 .了解这些机制将有助于优化SQL,提高数据库性能。

Mysql里的锁(排它锁、共享锁、行锁、表锁、间隙锁、临键锁、意向锁)

我记得有一次我正在处理数据库中一项复杂的数据更新任务。
当时,我坐在办公室的电脑前,屏幕上闪动着各种SQL语句。
突然间,系统变得极其缓慢。
我怀疑是网络问题,但看起来不是。
于是我打开一个新窗口,开始查看MySQL文档来找出原因。

就在那时我注意到了锁的概念。
记得有一次培训时,讲师提到如果事务中使用了错误的加锁策略,会导致锁等待甚至死锁。
我记得当时有一个例子:一个用户进行了范围查询,同时另一个用户更新了这个范围内的数据。
结果,更新事务陷入等待读取事务释放锁的状态。

检查了数据库的慢查询日志,发现存在这样的问题。
一个事务正在等待另一个事务释放特定行上的排他锁。
我意识到这就是导致系统速度变慢的原因。

我决定调整代码并优化锁的使用。
具体来说,我改用行锁来代替之前的表锁,因为行锁粒度更细,可以减少锁的等待时间。
我还将事务的隔离级别从默认的 REPEATABLE READ 调整为 READ COMMITTED 以减少锁争用。

调整后,系统的响应速度得到了显着提升。
这次经历让我深刻理解了锁在数据库中的作用,以及如何通过明智地使用锁来提高数据库的性能和稳定性。
等等,还有一件事。
我突然想到,在高并发场景下,即使行锁的粒度很小,也会导致更多的锁争用,那怎么办呢?

mysql什么情况下会出现锁表

这是一个坑。
2 008 年,Oracle因表锁导致事务延迟一个多小时。
不要相信长久的事情。
不要这样做。

mysql如何用事务和锁 锁住某一行数据,使得不允许两个用户同时读取一行数据!!

哎呀,不得不说一下这个数据库锁。

记得有一次,公司举办活动,系统突然死机了。
经查,发现有两个用户同时修改同一条订单信息。
结果,一方面减少了库存,另一方面增加了库存。
最后,数据不匹配。
顾客的投诉太多了,老板紧张得跳了起来。

换句话说,要使用MySQL,您需要知道如何锁定行。
否则,你的数据将会混乱,并且会造成严重的后果。

在MySQL中,如果你想锁定一行数据,让其他人无法访问它,最常用的方法是使用事务并添加SELECT ... FOR UPDATE语句。
示例:
SQL 开始交易。
从订单 WHERE order_id = 1 004 中选择进行续订。
更新订单设置数量 = 数量
1 WHERE order_id = 1 004 ; 提交;
这样做可以防止其他事务在该事务提交之前修改 order_id 1 004 的数据行。
这类似于拿起火车票并占据座位,从而阻止其他人登上火车。

读写锁。
简单地说,读与读并不矛盾,但读与写却是相互排斥的。
写作和写作绝对是相互排斥的。
当您在共享模式下创建 SELECT...LOCK 时,它会变成读锁。
其他事务也可以读取,但不能写入。
如果要写,必须先等待读锁被释放。

表锁和行锁因存储引擎而异。
InnoDB支持行锁,而MyISAM只支持表锁。
如今,InnoDB 普遍使用行锁。

如果您确实想谈论行锁定的演示,那没问题。
首先尝试创建一个表:
sql 创建表订单( order_id INT 主键, 数量 INT );
插入订单 (order_id, 数量) VALUES (1 001 , 1 0);
然后在两个不同的会话中进行操作。

会议A: SQL 开始交易。
从订单 WHERE order_id = 1 001 中选择进行更新。
更新订单设置数量 = 数量
1 WHERE order_id = 1 001 ; 提交;
会话B,如果也选择了同一行:
sql 开始交易。
从订单 WHERE order_id = 1 001 中选择进行更新。
-
该语句将等待会话 A 解锁。
更新订单设置数量 = 数量
1 WHERE order_id = 1 001 ; 提交;
可以看到会话 B 的 SELECT 会一直等到会话 A 的 UPDATE 发送或回滚后才能继续。
这就是加锁的效果。

但是,如果会话B操作不同的行,例如order_id = 1 002 ,则完全没问题,不会互相阻塞。
它们不会像你坐在 A 座位和我坐在 B 座位上那样相互影响。

了解行锁定将使您的系统更加稳定。
只有当你遇到问题的时候,你才会意识到这有多重要。
不要等到事情发生了才后悔。