MySQL - 表锁定

MySQL - 表锁定 首页 / MySQL入门教程 / MySQL - 表锁定

锁是与表相关联的一种机制,用于限制对表中数据的未授权访问。 MySQL允许客户端会话明确获取表锁,以与其他会话协作以访问表数据。 MySQL还允许表锁定,以防止在特定时间段内未经授权将其修改为同一表。

MySQL中的会话只能为其自身获取或释放表上的锁。因此,一个会话无法获取或释放其他会话的表锁。请注意,无涯教程必须具有表锁定和表锁定的SELECT特权。

MySQL中的表锁定主要用于解决并发问题。将在运行事务时使用它,即首先从表(数据库)中读取一个值,然后将其写入表(数据库)中。

MySQL在表上提供两种类型的锁:

读取锁(READ LOCK)    -  此锁允许用户仅从表中读取数据。

写锁定(WRITE LOCK)  -  该锁允许用户读取和写入表。

注意,MySQL中使用的默认存储引擎是InnoDB。 InnoDB存储引擎不需要手动锁定表,因为MySQL自动为InnoDB表使用行级锁定。因此,无涯教程可以在同一个表上同时执行多个事务以读取和写入操作,而无需彼此等待。所有其他存储引擎都使用MySQL中的表锁定。

在理解表锁定概念之前,首先,无涯教程将使用以下语句创建一个名为" info_table "的新表:

CREATE TABLE info_table ( 
    Id INT NOT NULL AUTO_INCREMENT, 
    Name VARCHAR(50) NOT NULL, 
    Message VARCHAR(80) NOT NULL,
    PRIMARY KEY (Id) 
);

LOCK语句

以下是允许无涯教程显式获取表锁的语法:

LOCK TABLES table_name [READ | WRITE];

在上述语法中,无涯教程已经指定了表名,在 LOCK TABLES 关键字之后,希望在该表名上获得锁定。可以指定锁定类型,即READ或WRITE。

无涯教程还可以通过使用带锁类型的逗号分隔表名列表来锁定MySQL中的多个表。请参见以下语法:

LOCK TABLES tab_name1 [READ | WRITE], 
            tab_name2 [READ | WRITE],...... ;

UNLOCK语句

以下是允许无涯教程释放MySQL中表的锁的语法:

mysql> UNLOCK TABLES;

读锁(Read Lock)

以下是READ锁定的函数:

  • 同时,MySQL允许多个会话获取表的READ锁。其他所有会话都可以在不获取锁的情况下读取表。
  • 如果会话在表上拥有READ锁,则他们无法在该表上执行写操作。这是因为READ锁只能从表中读取数据。所有其他不具有READ锁定的会话,如果不释放READ锁定,则无法将数据写入表中。写入操作进入等待状态,直到无涯教程还没有释放READ锁。
  • 当会话正常或异常终止时,MySQL隐式释放对该表的所有类型的锁。此函数也与WRITE锁定有关。

让无涯教程举一个例子来看一下在给定情况下READ锁在MySQL中如何工作。将首先连接到数据库,并使用 CONNECTION_ID()函数在第一个会话中提供当前连接ID,如下所示:

mysql> SELECT CONNECTION_ID();

请参见以下输出:

MySQL Table Locking

接下来,无涯教程将使用以下语句在 info_table 中插入几行:

mysql> INSERT INTO info_table (name, message) 
VALUES('Peter', 'Hi'),
('Joseph', 'Hello'),
('Mark', 'Welcome');

现在,使用以下语句将数据验证到表中:

mysql> SELECT * FROM info_table;

无涯教程应该看到如下输出:

MySQL Table Locking

现在,无涯教程将执行LOCK TABLE语句以获取对该表的锁定:

mysql> LOCK TABLE info_table READ;

之后,将尝试将新记录插入到info_table中,如下所示:

无涯教程网

mysql> INSERT INTO info_table (name, message) 
VALUES ('Suzi', 'Hi');

无涯教程将获得以下输出,其中MySQL发出以下消息"Table 'info_table' was locked wiwth a READ lock and can't be updated"

MySQL Table Locking

因此,无涯教程可以看到,一旦在表上获得了READ锁,就无法在同一会话中将数据写入表中。

现在,将检查其他会话中的READ锁定如何工作。首先,将连接到数据库并查看连接ID:

MySQL Table Locking

接下来,无涯教程将从info_table查询返回以下输出的数据:

MySQL Table Locking

然后,将一些行插入到此表中,如下所示:

mysql> INSERT INTO info_table (name, message) 
VALUES ('Stephen', 'Hello');

无涯教程应该看到如下输出:

MySQL Table Locking

在上面的输出中,可以看到第二个会话的插入操作处于等待状态。这是由于READ锁所致,该锁已由第一个会话在表上获取,但尚未释放。

无涯教程可以在第一个会话中使用SHOW PROCESSLIST语句查看有关它们的详细信息。请参见以下输出:

MySQL Table Locking

最后,无涯教程需要在第一个会话中使用 UNLOCK TABLES 语句释放锁定。现在,可以在第二个会话中执行INSERT操作。

写锁(Write Lock)

以下是WRITE锁的函数:

  • 这是持有表锁并可以从表中读取和写入数据的会话。
  • 这是唯一通过持有锁访问表的会话。在释放WRITE锁定之前,所有其他会话都无法访问表的数据。

让无涯教程举一个例子,看看在给定的情况下WRITE锁如何在MySQL中工作。在第一个会话中,将使用以下语句获取WRITE锁:

mysql> LOCK TABLE info_table WRITE;

然后,将新记录插入到info_table中,如下所示:

mysql> INSERT INTO info_table (name, message) 
VALUES ('Stephen', 'How R U');

上面的声明起作用了。现在,无涯教程可以使用SELECT语句验证输出:

MySQL Table Locking

同样,无涯教程将尝试从第二个会话访问(读/写)表:

INSERT INTO info_table (name, message) 
VALUES ('George', 'Welcome');

SELECT * FROM info_table;

无涯教程可以看到这些操作已进入等待状态。使用SHOW PROCESSLIST语句查看有关它们的详细信息:

MySQL Table Locking

最后,无涯教程将在第一个会话中释放该锁。现在,可以执行挂起的操作。

读锁与写锁

  • 读取锁类似于"共享"锁,因为多个线程可以同时获取它。
  • 写锁是"专有"锁,因为另一个线程无法读取它。
  • 无涯教程无法同时在表上提供读写锁。
  • 读取锁定的优先级比写入锁定的优先级,这可以确保尽快进行更新。

祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)

技术教程推荐

微服务架构核心20讲 -〔杨波〕

技术领导力实战笔记 -〔TGO鲲鹏会〕

深入浅出计算机组成原理 -〔徐文浩〕

SQL必知必会 -〔陈旸〕

现代C++编程实战 -〔吴咏炜〕

实用密码学 -〔范学雷〕

陶辉的网络协议集训班02期 -〔陶辉〕

Spring编程常见错误50例 -〔傅健〕

Web漏洞挖掘实战 -〔王昊天〕

好记忆不如烂笔头。留下您的足迹吧 :)