mysql 一个会话独占表_MySQL的SQL语句事务性语句和锁定语句5LOCKTABLES和UNLOCKTABLES 语句1...

LOCK TABLES 和 UNLOCK TABLES 语句

1. LOCK TABLES

2. tbl_name [[AS] alias] lock_type

3. [, tbl_name [[AS] alias] lock_type] ...

4.

5. lock_type: {

6. READ [LOCAL]

7. | [LOW_PRIORITY] WRITE

8. }

9.

10. UNLOCK TABLES

MySQL 允许客户端会话显式获取表锁,以便与其他会话协作访问表,或者在会话需要独占访问表时阻止其他会话修改表。会话只能获取或释放自身的锁。一个会话无法获取另一个会话的锁或释放另一个会话持有的锁。

锁可用于模拟事务或在更新表时获得更快的速度。

LOCK TABLES 显式获取当前客户端会话的表锁。可以对基本表或视图获取表锁定。要锁定对象,必须具有对象的 LOCK TABLES 权限和 SELECT 权限。

对于视图锁定,LOCK TABLES 将视图中使用的所有基本表添加到要锁定的表集合中,并自动锁定它们。对于被锁定的任何视图的底层表,LOCK TABLES 检查视图定义者(SQL SECURITY DEFINER 视图)或调用者(所有视图)是否对表具有适当的权限。

如果使用 LOCK TABLES 显式锁定表,则触发器中使用的任何表也将隐式锁定。

如果使用 LOCK TABLES 显式锁定表,则任何与外键约束相关的表都将被隐式打开和锁定。对于外键检查,对相关表使用共享只读锁(LOCK TABLES READ)。对于级联更新,对操作中涉及的相关表执行无共享的写入锁(LOCK TABLES WRITE)。

UNLOCK TABLES 显式释放当前会话持有的所有表锁。LOCK TABLES 在获取新锁之前隐式释放当前会话持有的所有表锁。

UNLOCK TABLES 的另一个用途是释放用 FLUSH TABLES WITH READ LOCK 语句获取的全局读锁,它能够锁定所有数据库中的所有表。(如果您的文件系统(如 Veritas)可以及时获取快照,则这是一种非常方便的备份方法。)

表锁只保护其他会话的不适当的读写操作。持有 WRITE 锁的会话可以执行诸如 DROP TABLE 或 TRUNCATE TABLE 之类的表级操作。对于持有 READ 锁的会话,不允许执行 DROP TABLE 和 TRUNCATE TABLE 操作。

以下讨论仅适用于非临时表。对于临时表,允许(但忽略)LOCK TABLES 语句。表可以由创建它的会话自由访问,无论其他什么锁定在生效。其实根本无需锁定,因为没有其他会话可以看到该表。

表锁的获取

要在当前会话中获取表锁定,请使用 LOCK TABLES 语句,该语句将获取元数据锁。

以下锁类型可用:

READ [LOCAL] 锁定:

● 持有锁的会话可以读取表(但不能写表)。

● 多个会话可以同时获取表的 READ 锁。

● 其他会话可以在不显式获取 READ 锁的情况下读取表。

● LOCAL 修饰符使其他会话的非冲突 INSERT 语句(并发插入)能够在保持锁的同时执行。但如果要在持有锁的同时使用服务器外部的进程操作数据库,则不能使用 READ LOCAL。对于 InnoDB 表,READ LOCAL 与 READ 相同。

[LOW_PRIORITY] WRITE 锁定:

● 持有锁的会话可以读写表。

● 只有持有锁的会话才能访问表。在释放锁之前,没有其他会话可以访问它。

● 当保持 WRITE 锁时,其他会话对表的锁定请求将被阻止。

● LOW_PRIORITY 修饰符无效。在以前版本的 MySQL 中,它影响锁定行为,但现在不再是这样了。它现在已被弃用,使用它会产生警告。请改用不带 LOW_PRIORITY 的 WRITE。

WRITE 锁通常比 READ 锁具有更高的优先级,以确保尽快处理更新。这意味着,如果一个会话获得一个 READ 锁,然后另一个会话请求一个 WRITE 锁,那么后续的 READ 锁请求会一直等到请求 WRITE 锁的会话获得并释放了锁。(对于 max_write_lock_count 系统变量的较小值,可能会出现此策略的例外。)

如果由于任何表上的其他会话持有锁,LOCK TABLES 语句必须等待,那么它将阻塞,直到可以获取所有锁。

需要锁的会话必须在单个 LOCK TABLES 语句中获取所需的所有锁。当这样获得的锁被持有时,会话只能访问锁定的表。例如,在以下语句序列中,尝试访问 t2 时出错,因为 t2 在 LOCK TABLES 语句中未被锁定:

1. mysql> LOCK TABLES t1 READ;

2. mysql> SELECT COUNT(*) FROM t1;

3. +----------+

4. | COUNT(*) |

5. +----------+

6. | 3 |

7. +----------+

8. mysql> SELECT COUNT(*) FROM t2;

9. ERROR 1100 (HY000): Table 't2' was not locked with LOCK TABLES

INFORMATION_SCHEMA 数据库中的表是一个例外。即使有会话持有通过 LOCK TABLES 获得的表锁,也可以在不显式锁定的情况下访问它们。

不能在同一个查询中使用相同的名称多次引用锁定的表。使用别名代替,并为表和每个别名获得一个单独的锁:

1. mysql> LOCK TABLE t WRITE, t AS t1 READ;

2. mysql> INSERT INTO t SELECT * FROM t;

3. ERROR 1100: Table 't' was not locked with LOCK TABLES

4. mysql> INSERT INTO t SELECT * FROM t AS t1;

第一个 INSERT 语句出错,因为对锁定的表有两个同名引用。第二个 INSERT 成功,因为对表的引用使用不同的名称。

如果语句通过别名引用表,则必须使用同一别名锁定表:

1. mysql> LOCK TABLE t READ;

2. mysql> SELECT * FROM t AS myalias;

3. ERROR 1100: Table 'myalias' was not locked with LOCK TABLES

相反,如果使用别名锁定表,则必须在语句中使用该别名引用表:

1. mysql> LOCK TABLE t AS myalias READ;

2. mysql> SELECT * FROM t;

3. ERROR 1100: Table 't' was not locked with LOCK TABLES

4. mysql> SELECT * FROM t AS myalias;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值