Postgres写/读锁
问题描述:
我有多线程JEE应用程序运行SELECT FOR UPDATE LIMIT 1;使用WHERE子句在表上查询并在每个事务中更新行,这会创建行级写入锁定并且不会阻止读取器读取。Postgres写/读锁
有没有什么办法可以配置postgres,阻止读者使用写入锁读取行?
答
在Postgres的9.5+存在SKIP LOCKED
选项:
如果您需要从表中选择和保护那些行被更新,直到您的交易完成后,您会指定FOR UPDATE,但如果一些行被锁定,您可以指定SKIP LOCKED来指示它忽略这些行,并只对可以访问的行执行操作。
https://wiki.postgresql.org/wiki/What's_new_in_PostgreSQL_9.5#SKIP_LOCKED
答
这里是你的选择,如果你是runnint Postgres的< = 9.4,其中NOWAIT
存在,但SKIP LOCKED
。这演示了在LOOP
中使用CONTINUE
和EXIT
以便识别下一个可用的解锁单行。
DO $$
DECLARE
r RECORD;
... -- your variables
BEGIN
FOR r IN
SELECT some_id
FROM some_table
WHERE ... -- your conditions
ORDER BY ... -- your ordering
LIMIT ... -- your limit
LOOP
BEGIN
SELECT ... -- your needed column(s)
INTO ... -- your defined variable(s)
FROM some_table -- the same table
WHERE some_id = r.some_id -- only check this one record
FOR UPDATE NOWAIT; -- don't wait for parallel transactions
EXIT;
EXCEPTION WHEN lock_not_available THEN
CONTINUE;
END;
END LOOP;
... -- do something based on variables, or move this before the EXIT above
END;
$$ LANGUAGE plpgsql;