锁是与表相关联的一种机制,用于限制对表中数据的未授权访问。 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 TABLES table_name [READ | WRITE];
在上述语法中,无涯教程已经指定了表名,在 LOCK TABLES 关键字之后,希望在该表名上获得锁定。可以指定锁定类型,即READ或WRITE。
无涯教程还可以通过使用带锁类型的逗号分隔表名列表来锁定MySQL中的多个表。请参见以下语法:
LOCK TABLES tab_name1 [READ | WRITE], tab_name2 [READ | WRITE],...... ;
以下是允许无涯教程释放MySQL中表的锁的语法:
mysql> UNLOCK TABLES;
以下是READ锁定的函数:
让无涯教程举一个例子来看一下在给定情况下READ锁在MySQL中如何工作。将首先连接到数据库,并使用 CONNECTION_ID()函数在第一个会话中提供当前连接ID,如下所示:
mysql> SELECT CONNECTION_ID();
请参见以下输出:
接下来,无涯教程将使用以下语句在 info_table 中插入几行:
mysql> INSERT INTO info_table (name, message) VALUES('Peter', 'Hi'), ('Joseph', 'Hello'), ('Mark', 'Welcome');
现在,使用以下语句将数据验证到表中:
mysql> SELECT * FROM info_table;
无涯教程应该看到如下输出:
现在,无涯教程将执行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" 。
因此,无涯教程可以看到,一旦在表上获得了READ锁,就无法在同一会话中将数据写入表中。
现在,将检查其他会话中的READ锁定如何工作。首先,将连接到数据库并查看连接ID:
接下来,无涯教程将从info_table查询返回以下输出的数据:
然后,将一些行插入到此表中,如下所示:
mysql> INSERT INTO info_table (name, message) VALUES ('Stephen', 'Hello');
无涯教程应该看到如下输出:
在上面的输出中,可以看到第二个会话的插入操作处于等待状态。这是由于READ锁所致,该锁已由第一个会话在表上获取,但尚未释放。
无涯教程可以在第一个会话中使用SHOW PROCESSLIST语句查看有关它们的详细信息。请参见以下输出:
最后,无涯教程需要在第一个会话中使用 UNLOCK TABLES 语句释放锁定。现在,可以在第二个会话中执行INSERT操作。
以下是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语句验证输出:
同样,无涯教程将尝试从第二个会话访问(读/写)表:
INSERT INTO info_table (name, message) VALUES ('George', 'Welcome'); SELECT * FROM info_table;
无涯教程可以看到这些操作已进入等待状态。使用SHOW PROCESSLIST语句查看有关它们的详细信息:
最后,无涯教程将在第一个会话中释放该锁。现在,可以执行挂起的操作。
祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)