跳到主要内容

锁定查询结果 LOCK IN SHARE MODE

SELECT ... LOCK IN SHARE MODE 用于在查询数据时获取共享锁,防止其他事务对数据进行写操作,但允许其他事务对数据进行读操作。即使用该语句时,会在读取的数据行上设置共享模式锁定,其他会话可以读取这些行,但在当前事务提交之前其他事务不能对其进行修改。

提示

seekdb 模拟了 LOCK IN SHARE MODE 共享锁语法的功能,使用写锁来实现,这样可以满足一些软件的兼容性需求,同时保证语法的正确性。由于使用写锁会使添加了 LOCK IN SHARE MODE 命令的读操作之间相互阻塞,因此一般不建议使用该语法,特别是在性能敏感的场景中更应该避免使用。

本文通过示例介绍如何使用 SELECT ... LOCK IN SHARE MODE 锁定查询结果。

示例

  1. 会话 1 中,执行下面 SQL 语句开启事务。

    START TRANSACTION;
  2. 会话 1 中,使用 LOCK IN SHARE MODE 语法在表 test_tbl1 中对 id 值等于 1 的记录进行查询,并获取共享锁。

    SELECT * FROM test_tbl1 WHERE id = 1 LOCK IN SHARE MODE;

    返回结果如下:

    +------+------+
    | id | name |
    +------+------+
    | 1 | A1 |
    +------+------+
    1 row in set
  3. 会话 2 中,执行下面 SQL 语句开启事务。

    START TRANSACTION;
  4. 会话 2 中,执行下面 SQL 语句查询表 test_tbl1id 值等于 1 的记录。

    SELECT * FROM test_tbl1 WHERE id = 1;

    返回结果如下:

    +------+------+
    | id | name |
    +------+------+
    | 1 | A1 |
    +------+------+
    1 row in set
  5. 会话 2 中,执行下面 SQL 语句在表 test_tbl1id 值等于 1 的行对应的 name 的改为 'A1A1A1'。该 SQL 语句会等待,直到 会话 1 的事务回滚或者 COMMIT 才得到执行。

    UPDATE test_tbl1 SET name = 'A1A1A1' WHERE id = 1;

    返回结果如下:

    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
  6. 会话 1 中,执行下面 SQL 语句提交事务。

    COMMIT;
  7. 会话 2 中,再次执行 步骤 4 的更新语句。

    UPDATE test_tbl1 SET name = 'A1A1A1' WHERE id = 1;

    返回结果如下:

    Query OK, 1 row affected
    Rows matched: 1 Changed: 1 Warnings: 0

相关文档

SELECT