跳到主要内容

LOCK TABLES

描述

该语句用于在会话(Session)中对表进行锁定,用于防止其他会话对同一表进行并发操作。当需要停止对某个表的所有 DML 和 DDL 操作时,可以使用该语句对表进行锁定。

前提条件

  • 使用 LOCK TABLES 语句前,需要打开如下配置项:

    ALTER SYSTEM SET enable_lock_priority = TRUE;

    上述配置项详细介绍,参见 enable_lock_priority

使用限制及注意事项

  • 在打开表锁以后,不建议单独进行 RENAME TABLE,在 RENAME TABLE 前建议先获取写锁(WRITE)锁。
  • 同 Session 上锁后,不支持读写上锁表,只允许 RENAME TABLE 操作。
  • 表别名(alias)上锁和表原名上锁相同。
  • 当前 Session 持有表锁时,再次执行 LOCK TABLES 时,会上多个表锁。
  • START TRANSACTION 不会解锁,必须通过 UNLOCK TABLES 或者 Session 断开后解除锁。
  • LOCK TABLES 不主动提交事务。
  • 不支持视图(View)上锁。
  • 触发器/外键涉及的表中只对原表上锁。例如:在外键涉及的表中对子表上锁,父表不会上锁;对父表上锁,子表不会上锁。
  • LOCK TABLES 语句的操作对象是临时表时,不上锁,不报错。

权限要求

执行 LOCK TABLES 语句,需要当前用户至少拥有对应对象的 LOCK TABLES 权限。有关 seekdb 权限的详细介绍,参见 seekdb 的权限分类

语法

LOCK {TABLE | TABLES}
tbl_name [[AS] alias] lock_type
[, tbl_name [[AS] alias] lock_type ...];

lock_type:
READ [LOCAL]
| [LOW_PRIORTY] WRITE

语法说明

字段名称描述
LOCK {TABLE | TABLES}表示对表或多个表进行锁定操作。LOCK TABLELOCK TABLES 的同义词。
table_name指定要锁定表的名称。
[AS] alias表示给表指定一个别名。
lock_type指定表锁定的类型。有关表锁定类型的详细介绍可参见下文 lock_type

lock_type

  • READ [LOCAL]

    • READ:表示所有的 Session 只能读取被锁的表,不能对该表进行修改(包括执行锁的 Session)。支持多个 Session 同时进行读取锁定操作。
    • READ LOCAL:与 READ 表现相同。
  • [LOW_PRIORTY] WRITE

    • WRITE:表示对表进行写入锁定操作。当前版本 WRITE 不影响读。
    • LOW_PRIORTY WRITE:与 WRITE 表现相同。

示例

  1. 创建示例表并插入测试数据。

    1. 创建表 test_tbl1

      CREATE TABLE test_tbl1(col1 INT, col2 VARCHAR(25), col3 INT);
    2. 向表 test_tbl1 中插入测试数据。

      INSERT INTO test_tbl1 VALUES(1, 'A1', 100);
  2. 打开配置项 enable_lock_priority

    ALTER SYSTEM SET enable_lock_priority = TRUE;
  3. 执行如下语句,提交事务。

    COMMIT;
  4. 在会话 1 中执行如下语句,为 test_tbl1 表设置读锁。

    LOCK TABLES test_tbl1 READ;
  5. 在会话 1 中执行如下语句,查看表 test_tbl1 数据。

    SELECT * FROM test_tbl1;

    返回结果如下:

    +------+------+------+
    | col1 | col2 | col3 |
    +------+------+------+
    | 1 | A1 | 100 |
    +------+------+------+
    1 row in set (0.001 sec)
  6. 在会话 1 中执行如下语句,向表 test_tbl1 中插入一行数据。

    INSERT INTO test_tbl1 VALUES(2, 'A2', 200);

    返回结果如下:

    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
  7. 在会话 2 中执行如下语句,查看表 test_tbl1 数据。

    SELECT * FROM test_tbl1;

    返回结果如下:

    +------+------+------+
    | col1 | col2 | col3 |
    +------+------+------+
    | 1 | A1 | 100 |
    +------+------+------+
    1 row in set (0.001 sec)
  8. 在会话 2 中执行如下语句,向表 test_tbl1 中插入一行数据。

    INSERT INTO test_tbl1 VALUES(2, 'A2', 200);

    返回结果如下:

    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
  9. 在会话 1 中执行如下语句,释放当前会话持有的所有表锁。

    UNLOCK TABLES;
  10. 在会话 1 中执行如下语句,向表 test_tbl1 中插入一行数据。

    INSERT INTO test_tbl1 VALUES(2, 'A2', 200);

    返回结果如下:

    Query OK, 1 row affected
  11. 在会话 2 中执行如下语句,向表 test_tbl1 中插入一行数据。

    INSERT INTO test_tbl1 VALUES(3, 'A3', 300);

    返回结果如下:

    Query OK, 1 row affected

相关文档

UNLOCK TABLES