关键字:人大金仓、KingbaseES、SELECT FOR UPDATE WAIT
SELECT FOR UPDATE WAIT
语法
[ WITH [ RECURSIVE ] with_query [, ...] ]
SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
[ * | expression [ [ AS ] output_name ] [, ...] ]
[ FROM from_item [, ...] ]
[ WHERE condition ]
[ GROUP BY grouping_element [, ...] ]
[ HAVING condition [, ...] ]
[ WINDOW window_name AS ( window_definition ) [, ...] ]
[ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ]
[ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST |
LAST } ] [, ...] ]
[ LIMIT { count | ALL } ]
[ OFFSET start [ ROW | ROWS ] ]
[ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]
[ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF table_name
[, ...] ] [ NOWAIT | SKIP LOCKED | WAIT seconds ] [...] ]
在SELECT语句中,FOR UPDATE子句允许锁定选定的行,使得其它会话无法在当前事务结束前锁定或者更新这些行。其中WAIT seconds新增语法部分,表示SELECT FOR UPDATE最多可等待的秒数。
FOR UPDATE、FOR NO KEY UPDATE、FOR SHARE和FOR KEY SHARE 是锁定子句,它们影响SELECT把行从表中取得时如何对它们加锁。
锁定子句的一般形式:
FOR lock_strength [ OF table_name [, ...] ] [ NOWAIT | SKIP LOCKED ] |
其中lock_strength可以是
UPDATE NO KEY UPDATE SHARE KEY SHARE |
规则
(1)FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE }均支持WAIT语法。
(2)WAIT seconds参数范围:0 ~ INT_MAX/1000,即0~2147483,单位为秒。0表示无限等待,直到行可用才会返回结果集,效果等同于省略NOWAIT、SKIP LOCKED和WAIT seconds 三个参数。
(3)指定WAIT后,SELECT FOR UPDATE在行变为可用之前最多等待seconds秒,如果等待成功则返回结果集,否则报错返回。
(4)只有最外层查询的锁定子句中的WAIT参数有效。
(5)公共表表达式、视图、子查询和子连接中的锁定子句的WAIT参数无效,锁定子句效果等同于默认策略(无限等待)。
(6)一次查询中只能支持一个锁定子句,当查询中指定多个锁定子句时,所有子句中的WAIT参数均无效。
(7)锁定子句不能和UNION/INTERSECT/EXCEPT子句、DISTINCT子句、GROUP BY子句、HAVING子句、聚集函数、窗口函数,以及集合返回函数一起使用。
(8)锁定子句不能应用于FROM函数、TABLE函数、VALUES子句和WITH查询。当不指定锁定表名时,遇到这些类型范围表将直接忽略;当指定了锁定表名时,遇到这些类型的范围表将会报错。
(9)除了可在常规表查询中使用锁定子句之外,还可以在视图、子查询和WITH子句内部使用锁定子句。
数据准备
(1)创建数据表并插入数据
test=# create table tab (id int, data serial);
CREATE TABLE
test=# insert into tab values (1, default);
INSERT 0 1
(2)查看数据表
test=# select * from tab;
id | data
----+------
1 | 1
(1 row)
使用场景
(1)FOR UPDATE
test=# select * from tab for update wait 5;
id | data
----+------
1 | 1
(1 row)
(2)FOR NO KEY UPDATE
test=#select * from tab for no key update wait 5;
id | data
----+------
1 | 1
(1 row)
test=# select * from tab for share wait 5;
id | data
----+------
1 | 1
(1 row)
(4)FOR KEY SHARE
test=# select * from tab for key share wait 5;
id | data
----+------
1 | 1
(1 row)
(5)limit value
test=# select * from tab for update wait 0;
id | data
----+------
1 | 1
(1 row)
test=# select * from tab for update wait 2147483;
id | data
----+------
1 | 1
(1 row)
(6)out of range
test=# select * from tab for update wait -1;
ERROR: syntax error at or near "-"
LINE 1: select * from tab for update wait -1;
test=# select * from tab for update wait 2147484;
ERROR: wait seconds out of range: 2147483
drop table tab;




