MySQL的意向共享锁、意向排它锁和死锁

MySQL意向锁和死锁攻略

意向锁

MySQL中有两种意向锁:意向共享锁(IS)和意向排它锁(IX)。当一个事务请求一张表的排它锁或者共享锁时,MySQL会先判断表是否已经被其它事务加了锁。若没有加锁,则直接获取锁;若被加锁,则会判断待加的锁类型。若是要请求共享锁,则会在表上加意向共享锁(IS);若是要请求排它锁,则会在表上加意向排它锁(IX)。意向锁只是一个标记而已,并不真正锁住了什么,其目的在于表示一个事务准备加一个类型的锁。

例如,事务A要获取一张表的共享锁(读锁),而该表当前未被锁住。那么,MySQL会在该表上加意向共享锁(IS)。之后,事务B也要获取该表的共享锁,MySQL会发现该表已经有了意向共享锁(IS),那么MySQL就知道有其它事务在该表上存在对该表的读操作,并不需要等待其它事务释放锁。

从意向锁的功能可以看出,意向锁是针对表级别的锁,而不是针对行级别的锁。

死锁

假设有两个事务T1和T2,T1在等待T2释放的锁,而同时T2也在等待T1释放的锁,那么这两个事务就产生了死锁。此时,系统一般会强制回滚其中一个事务,解除死锁的情况。

如下面所示的示例:

  • 执行以下SQL:
SET SESSION autocommit=0; --关闭自动提交
BEGIN; --开启一个事务
SELECT * FROM table1 WHERE id = 10 FOR UPDATE; --对表进行排他锁

上述SQL语句会对表table1中id等于10的一行进行排它锁(FOR UPDATE)。此时,该行的锁定时间会一直持续到当前事务提交或回滚。

  • 现在开启另外一个事务,并尝试获取该行的排它锁:
SET SESSION autocommit=0; --关闭自动提交
BEGIN; --开启一个事务
SELECT * FROM table1 WHERE id = 10 FOR UPDATE; --获取排它锁(FOR UPDATE)

此时,Notice如下提示:

MySQL on localhost (5.7.33)  Warning (1205): Lock wait timeout exceeded; try restarting transaction

它表示这个事务超时(由锁等待超时参数选项决定)了以后,还是没有获得需要的锁,MySQL就会强制回滚该事务。

在该示例中,如果两个事务先后执行,则T1成功获取该行的锁,而T2则始终在等待该锁的释放,最后会超时回滚,解除死锁的情况。

示例

接下来,我们来看一下具体的示例操作。

在该示例中,我们创建一个students表,然后模拟两个事务之间的死锁情况。

首先,我们创建一个students表:

CREATE TABLE `students` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

接着,我们往students表中插入一些记录:

INSERT INTO `students` (`name`, `age`) VALUES
  ('Tom', 18),
  ('Jack', 20),
  ('Lucy', 22),
  ('Mike', 24),
  ('David', 20),
  ('John', 22);

现在,我们让两个事务分别对students表进行操作。

  1. 第一个事务(T1)

在第一个事务中,我们首先查询students表中所有年龄为20岁的学生信息:

SET SESSION autocommit=0;
BEGIN;
SELECT * FROM students WHERE age = 20 FOR UPDATE;

上述SQL对students表中所有age为20的行进行了排它锁,该锁将一直存在于当前事务中。

  1. 第二个事务(T2)

在第二个事务中,我们对students表中年龄为22的行进行更新操作:

SET SESSION autocommit=0;
BEGIN;
UPDATE students SET age = age + 1 WHERE age = 22;

上述SQL需要在students表中获取一行排他锁(FOR UPDATE),但由于第一个事务已经持有了students表的排它锁,因此该事务将等待第一个事务的锁释放,直到超时后回滚。

在上述示例中,我们展示了MySQL意向锁和死锁的操作过程。需要注意的是,在实际应用中,我们通常需要注意编写高效的SQL语句,避免出现死锁等问题,同时也可以根据实际需求对MySQL锁相关的配置进行适当调整,以提高系统的性能和稳定性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:MySQL的意向共享锁、意向排它锁和死锁 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • SQL 根据字符串里的数字排序

    首先,SQL中可以使用ORDER BY语句对查询结果进行排序。如果需要对字符串中的数字进行排序,可以利用SQL中的函数来实现。 下面是两个SQL语句的示例,展示如何按照字符串中的数字进行排序: 使用CAST函数进行转换排序: SELECT id, name FROM table_name ORDER BY CAST(SUBSTR(name, 4) AS UN…

    database 2023年3月27日
    00
  • oracle数据库导入导出命令解析

    下面是Oracle数据库导入导出命令解析的完整攻略,主要包括导入和导出的流程以及常用的命令示例。 导出数据 步骤一:登陆数据库 使用以下命令登陆Oracle数据库: $ sqlplus 用户名/密码@实例名 其中,用户名、密码和实例名需要替换为实际的值。 步骤二:设置导出文件路径 执行以下命令设置导出文件路径: SQL> host mkdir /pat…

    database 2023年5月21日
    00
  • 数据库同步优化技巧分享

    数据库同步优化技巧分享 背景 数据库同步是指将一个数据库的数据迁移到另一个数据库的过程。在迁移数据的过程中,可能会遇到一些性能问题,例如同步速度缓慢、数据不一致等问题。因此,需要优化同步过程中的一些细节,以提高同步性能和减少同步时间。 优化技巧 1. 使用增量同步 数据库同步时,全量同步和增量同步是两种不同的方式。全量同步是指将整个数据库的数据全部复制到目标…

    database 2023年5月19日
    00
  • MySQL – change 和 modify 的区别

    表描述MySQL 中 change 和 modify 区别 更改列名 change: alter table 表名 change 旧列名 新列名 类型 只更改列属性 change: alter table 表名 列名 列名 类型 相同的列名要写两次. 更改列属性 modify: alter table 表名 列名 类型 区别:1)change 可以更改列名 …

    MySQL 2023年4月12日
    00
  • Linux下sersync数据实时同步

    关于 Linux 下 sersync 数据实时同步的攻略,我整理出了以下流程。 环境准备 安装 Linux 操作系统; 安装 sersync 软件,可以通过官方网站下载 sersync 软件; 准备同步的源文件夹和目标文件夹以及同步配置文件。 配置文件设置 配置文件的文件名为 sersync2.conf; 配置文件样本可通过官方网站获取到,样本文件名为 se…

    database 2023年5月22日
    00
  • Win2003系统安装SQL Server2000后1433端口未开放的解释

    Win2003系统安装SQL Server2000后1433端口未开放的解决方法如下: 1. 检查SQL Server配置 首先,需要检查SQL Server是否已配置为允许远程连接。具体步骤如下: 打开SQL Server Enterprise Manager。 在左侧导航栏中,展开“Microsoft SQL Servers”和 “[your serve…

    database 2023年5月22日
    00
  • MySQL正则表达式regexp_replace函数的用法实例

    关于MySQL正则表达式regexp_replace函数的用法实例,我来给您详细讲解一下。 标题 MySQL正则表达式regexp_replace函数的用法实例 介绍 MySQL正则表达式regexp_replace函数是一种处理文本的工具,可以在数据查询和数据清洗等场景中使用。其功能是在特定的字符串中使用正则表达式替换目标字符串,从而实现对数据的清洗和处理…

    database 2023年5月21日
    00
  • Centos8安装mysql8的详细过程(免安装版/或者二进制包方式安装)

    以下是CentOS 8安装MySQL 8的详细过程。 准备工作 在开始安装之前,需要在CentOS 8上安装一些依赖项以支持MySQL 8。在终端中运行以下命令: sudo dnf install wget curl vim sudo dnf install libaio sudo dnf install numactl 这些命令将安装wget、curl和v…

    database 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部