Innodb中常见SQL语句设置的锁类型

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: 1、select … from除了serializable隔离级别,这种SQL都是一致性非锁定读,不加锁;在serializable级别,这种SQL加next-key锁。2、select … from … lock in share mode这种SQL加S类型的next-key锁。

1、select … from

除了serializable隔离级别,这种SQL都是一致性非锁定读,不加锁;在serializable级别,这种SQL加next-key锁。

2、select … from … lock in share mode

这种SQL加S类型的next-key锁。例如,在会话1上开启事务1,执行如下操作(num列上建有普通二级索引):

mysql> start transaction;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from lock_test;
+----+-----+------+
| id | num | name |
+----+-----+------+
|  1 |   1 | jdd  |
|  2 |  43 | hjh  |
|  3 |   6 | ew   |
|  4 |   4 | dd   |
|  5 |  12 | t    |
|  6 |  32 | hu   |
| 32 |  45 | gj   |
+----+-----+------+
mysql> select * from lock_test where num=12 lock in share mode;
+----+-----+------+
| id | num | name |
+----+-----+------+
|  5 |  12 | t    |
+----+-----+------+

会话2上开启事务2,执行如下操作:

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into lock_test values(null,8,'hgj');
^C^C -- query aborted
ERROR 1317 (70100): Query execution was interrupted
mysql> insert into lock_test values(null,31,'hgj');
^C^C -- query aborted
ERROR 1317 (70100): Query execution was interrupted

插入num=8和31,都发生阻塞,说明事务1执行的语句产生了间隙锁。若再在事务2中执行语句“select * from lock_test where num=12 lock in share mode;”,不会发生阻塞,说明num=12上加的是S锁,所以锁兼容。

3、select … from … for update

这种SQL加X类型的next-key锁。

4、update … where …

RR及其以上隔离级别下,该语句会加next-key锁;在RC级别,只加record锁。

5、delete from … where …

RR及其以上隔离级别下,该语句会加next-key锁;在RC级别,只加record锁。

6、insert … values …

这里指简单的insert(simple insert),即不加ON DUPLICATE KEY UPDATE和select子句的insert语句。这种SQL语句只会在它插入的行上加X锁,而不会加next-key锁。

但是对于唯一列(unique列和主键列),如果多个事务向同一行插入数据,那么第一个事务持有该行的X锁,之后的事务将向这个重复的索引记录行上请求加S锁,并且此时发生锁等待现象。这个时候,还有可能会有死锁发生:

例如假设有个如下结构的innodb表:

CREATE TABLE t1 (i INT, PRIMARY KEY (i)) ENGINE = InnoDB;

假设有三个会话依次执行如下操作:

Session 1:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
Session 2:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
Session 3:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
Session 1:
ROLLBACK;

会话1获得i=1数据行上的X锁,之后会话2和会话3的操作因为可能会导致重复键错误,所以它们均请求i=1上的S锁而发生锁等待;当会话1回滚后,i=1数据行上的X锁被释放(或者说没有了i=1的行),此时锁请求队列里的会话2和会话3都可以获得S锁,但此时将产生死锁:由于它们都持有该数据行上的S锁,因此两个会话都获取不到数据行上的X锁。
上面的例子,如果i是unique key,情况也同样适用。

7、insert … on duplicate key update

该SQL与simple insert的不同之处在于,当发生重复键错误时,在要更新的行上设置X类型的next-key锁

8、insert into T select … from S where…

这种SQL在T表被插入的行上加X record lock;在S表上,若事务隔离级别不是SERIALIZABLE,innodb在S表上是一致性非锁定读方式(即不加锁)。如果是在SERIALIZABLE级别,innodb将在S表上加S类型的next-key锁。

9、create table … select …

加锁方式和insert … select方式相同。

10、lock tables

包括lock tables tb_name read/write语句,这种语句加的是表锁(table locks),设置表锁的是innodb层之上的MySQL server层

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
SQL 存储 Unix
Flink SQL 在快手实践问题之设置 Window Offset 以调整窗口划分如何解决
Flink SQL 在快手实践问题之设置 Window Offset 以调整窗口划分如何解决
158 2
|
6月前
|
SQL XML Java
六、MyBatis特殊的SQL:模糊查询、动态设置表名、校验名称唯一性
六、MyBatis特殊的SQL:模糊查询、动态设置表名、校验名称唯一性
143 0
|
8月前
|
SQL Java 数据库连接
如何在 Java 代码中使用 JSqlParser 解析复杂的 SQL 语句?
大家好,我是 V 哥。JSqlParser 是一个用于解析 SQL 语句的 Java 库,可将 SQL 解析为 Java 对象树,支持多种 SQL 类型(如 `SELECT`、`INSERT` 等)。它适用于 SQL 分析、修改、生成和验证等场景。通过 Maven 或 Gradle 安装后,可以方便地在 Java 代码中使用。
2412 11
|
10月前
|
SQL 关系型数据库 MySQL
|
10月前
|
SQL
开启慢SQL设置long_query_time=0.1为啥会统计的sql却存在小于100毫秒的sql
开启慢SQL设置long_query_time=0.1为啥会统计的sql却存在小于100毫秒的sql
153 1
|
11月前
|
SQL Java 数据库连接
mybatis使用四:dao接口参数与mapper 接口中SQL的对应和对应方式的总结,MyBatis的parameterType传入参数类型
这篇文章是关于MyBatis中DAO接口参数与Mapper接口中SQL的对应关系,以及如何使用parameterType传入参数类型的详细总结。
289 10
|
11月前
|
SQL 存储 数据库
SQL部分字段编码设置技巧与方法
在SQL数据库管理中,设置字段的编码对于确保数据的正确存储和检索至关重要
|
11月前
|
SQL 存储 关系型数据库
SQL判断CHAR类型字段不为空的方法与技巧
在SQL查询中,判断一个CHAR类型字段是否不为空是一个常见的需求
|
监控 关系型数据库 MySQL
在Linux中,mysql的innodb如何定位锁问题?
在Linux中,mysql的innodb如何定位锁问题?
|
SQL 数据处理 数据库
SQL中的函数有哪些类型
【8月更文挑战第20天】SQL中的函数有哪些类型
227 1