mysql - innodb 隔离级别和锁定

标签 mysql transactions innodb isolation-level database-locking

我正在阅读有关 innodb 事务的手册,但仍然有很多不清楚的地方。例如,我不太理解以下行为:

-- client 1                             -- client 2
mysql> create table simple (col int) 
       engine=innodb; 

mysql> insert into simple values(1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into simple values(2);
Query OK, 1 row affected (0.00 sec)

mysql> select @@tx_isolation;                                                              
+-----------------+                                                                         
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |                                                                         
+-----------------+

mysql> begin;                                    
Query OK, 0 rows affected (0.01 sec)            
                                        mysql> begin;
                                        Query OK, 0 rows affected (0.00 sec)

mysql> update simple set col=10 where col=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

                                         mysql> update simple set col=42 where col=2;
                                         -- blocks

现在,最后一个更新命令(在客户端 2 中)等待。我希望命令执行,因为我假设只有第 1 行被锁定。即使客户端 2 中的第二个命令是 insert,行为也是相同的。谁能描述一下这个例子背后的锁定背景(锁定的位置和原因)?

最佳答案

InnoDB 设置特定类型的锁如下。

  • SELECT ... FROM 是一致读取,读取数据库的快照并且不设置锁定,除非事务隔离级别设置为 SERIALIZABLE。对于 SERIALIZABLE 级别,搜索会在遇到的索引记录上设置共享的下一键锁。

  • SELECT ... FROM ... LOCK IN SHARE MODE 在搜索遇到的所有索引记录上设置共享的下一键锁。

  • 对于搜索遇到的索引记录,SELECT ... FROM ... FOR UPDATE 阻止其他 session 执行 SELECT ... FROM ... LOCK IN SHARE MODE 或读取某些事务隔离级别。一致读取将忽略读取 View 中存在的记录上设置的任何锁。

  • UPDATE ... WHERE ... 为搜索遇到的每条记录设置排他的下一键锁。

  • DELETE FROM ... WHERE ... 为搜索遇到的每条记录设置排他的下一键锁。

  • INSERT 在插入的行上设置排他锁。这个锁是index-record lock,不是next-key lock(即没有gap lock),不会阻止其他session插入插入行之前的gap。

InnoDB 有几种类型的记录级锁:

  • 记录锁:这是对索引记录的锁。

  • 间隙锁:这是对索引记录之间的间隙进行锁定,或者对第一条索引记录之前或最后一条索引记录之后的间隙进行锁定。

  • Next-key lock:这是索引记录上的记录锁和索引记录之前的间隙上的间隙锁的组合。

查看更多:

Avoiding the Phantom Problem Using Next-Key Locking

Avoiding deadlock

关于mysql - innodb 隔离级别和锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9354022/

相关文章:

mysql - 适合浴室的 MySQL 列类型

testing - 在测试中使用 fake-valid-nonce 创建交易时,交易结果显示消息 : "Gateway Rejected: duplicate”

mysql - 在 MySQL 中选择并更新几行而不发生冲突

MySQL 计数与分组依据

javascript - 使用 Node.js 和 MySQL 检查数据库中的现有元素

spring - 在tomcat上实现 Spring 交易的最佳方式

sql-server - 如何以编程方式在 SQL Server 中启用 READ COMMITTED SNAPSHOT?

mysql - InnoDB 到 MyISAM 转换奇怪的性能行为

mysql - 搜索距离邮政编码最近的 5 个位置 - 我应该走哪条路?

mysql - 将 MySQL 表导出到 Microsoft SQL 服务器