类别:

查询语法

FOR UPDATE

锁定查询选择的行,直至包含查询的事务提交或中止。

仅支持在混合表中使用此子句,此子句对于多个事务尝试同时访问相同行的事务工作负载非常有用。从某种意义上来说,在执行锁定的事务完全提交或回滚之前,其他事务无法向这些行写入数据,因此这些行是锁定的,不能更新。但其他事务可以读取锁定的行,并且可以读取、更新或删除同一个表中的其他行。

SELECT ...
  FROM ...
  [ ... ]
  FOR UPDATE [ NOWAIT | WAIT <wait_time> ]
Copy

参数

NOWAIT

如果事务无法立即锁定选定行,则返回错误。NOWAIT 是默认值。

WAIT wait_time

指定查询等待获取行级锁定的最长时间(以秒为单位)。如果等待时间到期,查询会返回错误。

限制

FOR UPDATE 子句:

使用说明

由于混合表支持 READ COMMITTED 隔离级别,因此 FOR UPDATE 子句不能保证读取稳定性。例如,假设表 T 包含一个名为 ID 的列,其中包含两行,值分别为 510

  1. 以下查询在事务 T1 中运行:

    SELECT * FROM T WHERE ID < 20 FOR UPDATE;
    
    Copy

    该查询返回 510 值并锁定这两行。

  2. 另一个事务 T2 运行以下 DELETE 操作:

    DELETE FROM T WHERE ID = 5;
    
    Copy

    事务 T2 必须等到 T1 完成(也就是说,直至其提交或回滚)。

  3. 但第三个事务 T3 可以完成以下 INSERT 操作:

    INSERT INTO T VALUES 12;
    
    Copy
  4. 现在,T1 中的后续查询返回三个值(行),而非两个:51012

    SELECT * FROM T WHERE ID < 20;
    
    Copy

示例

打开一个新事务,从混合表 (ht) 中选择所有行,然后锁定这些行,直至事务提交。在提交事务之前,更新一些选定行并运行另一个查询。

BEGIN;
...
SELECT * FROM ht ORDER BY c1 FOR UPDATE;
...
UPDATE ht set c1 = c1 + 10 WHERE c1 = 0;
...
SELECT ... ;
...
COMMIT;
Copy

为行锁定应用 60 秒的最大等待时间:

BEGIN;
...
SELECT * FROM ht FOR UPDATE WAIT 60;
...
COMMIT;
Copy
语言: 中文