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

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 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层

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
3月前
|
SQL Java 分布式数据库
Flink CDC HBase字段类型与Flink SQL类型之间的转换
【1月更文挑战第4天】【1月更文挑战第19篇】Flink CDC HBase字段类型与Flink SQL类型之间的转换
63 1
|
1月前
|
存储 关系型数据库 MySQL
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
175 0
|
3月前
|
SQL 关系型数据库 MySQL
Mysql系列-3.Mysql的SQL优化和锁(中)
Mysql系列-3.Mysql的SQL优化和锁
40 0
|
1月前
|
SQL 安全 API
|
2月前
|
SQL JSON 数据库
常见的sql注入类型闭合及符号
常见的sql注入类型闭合及符号
31 0
|
2月前
|
SQL 监控 Java
Flink报错问题之Flink sql tinyint类型使用in报错如何解决
Apache Flink是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎。本合集提供有关Apache Flink相关技术、使用技巧和最佳实践的资源。
|
2月前
|
SQL Java API
Flink超时问题之Flink sql cdc锁超时如何解决
Apache Flink是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎。本合集提供有关Apache Flink相关技术、使用技巧和最佳实践的资源。
|
2月前
|
SQL Serverless 数据库
SQL语句的类型
SQL语句的类型
|
3月前
|
SQL Perl
pl sql -00615错误,操作数和类型不一致问题
pl sql -00615错误,操作数和类型不一致问题
21 0
pl sql -00615错误,操作数和类型不一致问题
|
3月前
|
存储 算法 关系型数据库
MySQL相关(八)- innodb行级锁深入剖析
MySQL相关(八)- innodb行级锁深入剖析
45 0