- 类别:
FOR UPDATE¶
锁定查询选择的行,直至包含查询的事务提交或中止。
仅支持在混合表中使用此子句,此子句对于多个事务尝试同时访问相同行的事务工作负载非常有用。从某种意义上来说,在执行锁定的事务完全提交或回滚之前,其他事务无法向这些行写入数据,因此这些行是锁定的,不能更新。但其他事务可以读取锁定的行,并且可以读取、更新或删除同一个表中的其他行。
SELECT ...
FROM ...
[ ... ]
FOR UPDATE [ NOWAIT | WAIT <wait_time> ]
参数¶
NOWAIT
如果事务无法立即锁定选定行,则返回错误。NOWAIT 是默认值。
WAIT wait_time
指定查询等待获取行级锁定的最长时间(以秒为单位)。如果等待时间到期,查询会返回错误。
限制¶
FOR UPDATE 子句:
使用说明¶
由于混合表支持 READ COMMITTED 隔离级别,因此 FOR UPDATE 子句不能保证读取稳定性。例如,假设表 T
包含一个名为 ID
的列,其中包含两行,值分别为 5
和 10
。
以下查询在事务
T1
中运行:SELECT * FROM T WHERE ID < 20 FOR UPDATE;
该查询返回
5
和10
值并锁定这两行。另一个事务
T2
运行以下 DELETE 操作:DELETE FROM T WHERE ID = 5;
事务
T2
必须等到T1
完成(也就是说,直至其提交或回滚)。但第三个事务
T3
可以完成以下 INSERT 操作:INSERT INTO T VALUES 12;
现在,
T1
中的后续查询返回三个值(行),而非两个:5
、10
和12
:SELECT * FROM T WHERE ID < 20;
示例¶
打开一个新事务,从混合表 (ht
) 中选择所有行,然后锁定这些行,直至事务提交。在提交事务之前,更新一些选定行并运行另一个查询。
BEGIN;
...
SELECT * FROM ht ORDER BY c1 FOR UPDATE;
...
UPDATE ht set c1 = c1 + 10 WHERE c1 = 0;
...
SELECT ... ;
...
COMMIT;
为行锁定应用 60 秒的最大等待时间:
BEGIN;
...
SELECT * FROM ht FOR UPDATE WAIT 60;
...
COMMIT;