我有多線程JEE應用程序運行SELECT FOR UPDATE LIMIT 1;使用WHERE子句在表上查詢並在每個事務中更新行,這會創建行級寫入鎖定並且不會阻止讀取器讀取。Postgres寫/讀鎖
有沒有什麼辦法可以配置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;