mysql - 锁(S、X、IS、IX)如何在 Mysql 中使用 FOR UPDATE/LOCK IN SHARE MODE 之类的查询工作?

标签 mysql database concurrency transactions locking

1:

我正在尝试这个并且它工作正常:

start transaction; 
 select * from orders where id = 21548 LOCK IN SHARE MODE;
 update orders set amount = 1500 where id = 21548;
commit;

根据LOCK IN SHARE MODE的定义,用IS锁锁定表,用S锁锁定选中的行。

当一行被S锁锁定时,如何在不释放锁的情况下进行修改? 需要X锁才能修改吧?还是只对不同的连接交易有效?

2:

//session1
start transaction;
select * from orders where id = 21548 FOR UPDATE;

保持这个 session1 不变,然后在不同的 session 中尝试:

 //session2
 select * from orders where id = 21548; //working
 update orders set amount = 2000 where id = 21548; //waiting

FOR UPDATE 将整个表锁定为 IX 模式并将所选行锁定为 X 模式。

既然 X 模式与 S 模式不兼容,那么为什么在第二个 session 中执行选择查询?

一个答案可能是选择查询没有请求 S 锁,这就是它运行成功的原因。但是第二个 session 中的更新查询也没有请求 X 锁,但是当您执行它时,它开始等待持有的锁通过 session 1。

我已经阅读了很多关于这方面的资料,但无法消除我的疑虑。请帮忙。

最佳答案

Bill Karwin 通过电子邮件回答了这个问题。他说:

  1. 持有 S 锁的同一事务可以将锁提升为 X 锁。这不是冲突。

  2. session 1 中带有 FOR UPDATE 的 SELECT 获取 X 锁。没有指定锁定子句的简单 SELECT 查询不需要获取 S 锁。

任何 UPDATE 或 DELETE 都需要获取 X 锁。这是隐含的。这些语句没有任何特殊的锁定子句。

有关 IS/IX 锁和共享模式更新/锁的更多详细信息,请访问 shared-and-exclusive-locks .

关于mysql - 锁(S、X、IS、IX)如何在 Mysql 中使用 FOR UPDATE/LOCK IN SHARE MODE 之类的查询工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31880185/

相关文章:

mysql - 如何将 2 个不同的列分组在一起

mysql group 通过使用范围记录值

MySQL 在另一个字段中第一次出现某个值时设置标志

MySQL索引长度解释

database - 我可以作为数据库角色执行 Entity Framework 查询吗?

bash - 如何与 bash 同时处理文件?

php - 将数组从字段发送到 javascript,然后发送到 php

mysql - 如何为列选择优化数据类型 [innodb specific]?

Python 同时填充列表

postgresql - 外部数据包装并发请求