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日

相关文章

  • 对linux下syslogd以及syslog.conf文件的解读说明

    syslogd是Linux系统下的系统日志记录守护进程,它可以从应用程序、内核、系统日志文件等多个来源接收日志信息,然后将它们记录在指定的系统日志文件中。而syslog.conf文件则是用来配置syslogd的,它定义了syslogd的日志信息如何记录,保存在哪些文件中以及对于不同的设备、优先级和来源的日志信息的应答等的日志信息处理流程。 syslog.co…

    database 2023年5月22日
    00
  • 在Linux系统安装Mysql教程

    下面是在Linux系统安装Mysql的完整攻略: 安装Mysql 步骤一:安装Mysql 在Linux系统上安装Mysql需要使用Linux包管理器,可以使用以下命令在命令行界面中进行安装: Ubuntu 使用以下命令进行安装: sudo apt-get install mysql-server CentOS/RHEL 使用以下命令进行安装: sudo yu…

    database 2023年5月22日
    00
  • PostgreSQL 和 IBM DB2 的区别

    PostgreSQL和IBM DB2是两种常用的关系型数据库管理系统,二者都有着自己独特的优势和适用场景。下面将详细讲解它们之间的区别: 1. 数据库类型 PostgreSQL和IBM DB2在数据库类型方面有所不同。PostgreSQL属于开源的对象-关系型数据库管理系统,它支持多种数据类型,包括JSON、XML等。而IBM DB2属于商业化的关系型数据库…

    database 2023年3月27日
    00
  • 如何在Python中使用SQLAlchemy操作MySQL数据库?

    以下是如何在Python中使用SQLAlchemy操作MySQL数据库的完整使用攻略,包括安装SQLAlchemy、连接MySQL数据库、创建表、插入数据、查询数据等步骤。同时,提供了两个示例以便更好理解如何使用SQLAlchemy操作MySQL数据库。 步骤1:安装SQLAlchemy 在Python中,我们可以使用pip命令安装SQLAlchemy。以下…

    python 2023年5月12日
    00
  • 如何在Python中使用mysql-connector库连接MySQL数据库?

    以下是如何在Python中使用mysql-connector库连接MySQL数据库的完整使用攻略,包括安装mysql-connector库、连接MySQL数据库、执行SQL语句等步骤。同时,提供了两个示例以便更好解如何使用mysql-connector连接MySQL数据库。 步骤1:安装mysql-connector库 在Python中,我们可以使用pip命…

    python 2023年5月12日
    00
  • 数据库系列:覆盖索引和规避回表

    1 介绍 在MySQL数据库查询过程中,索引覆盖和避免不必要的回表,是减少检索步骤,提高执行效率的有效手段。下面从这两个角度分析如何进行MySQL检索提效。 2 数据准备 模拟一个500w数据容量的部门表 emp,表结构如下,并通过工具模拟500w的数据: CREATE TABLE `emp` ( `id` int unsigned NOT NULL AUT…

    2023年4月8日
    00
  • 三天吃透MySQL面试八股文

    什么是MySQL MySQL是一个关系型数据库,它采用表的形式来存储数据。你可以理解成是Excel表格,既然是表的形式存储数据,就有表结构(行和列)。行代表每一行数据,列代表该行中的每个值。列上的值是有数据类型的,比如:整数、字符串、日期等等。 数据库的三大范式 第一范式1NF 确保数据库表字段的原子性。 比如字段 userInfo: 广东省 10086′ …

    2023年4月8日
    00
  • 如何在Python中使用pymysql库连接MySQL数据库?

    以下是如何在Python中使用pymysql库连接MySQL数据库的完整使用攻略,包括安装pymysql库、连接MySQL数据库、执行SQL语句等骤。同时,提供了两个示例以便更好理解如何使用pymysql库连接MySQL数据库。 步骤1:安装pymysql库 在Python中,我们可以使用pip命令安装pymysql库。以下是安装pymysql库基本语法: …

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