我有多线程JEE应用程序,它运行SELECT FOR UPDATE LIMIT 1;在每个事务中使用WHERE子句和Update行查询表,这会创建行级写锁,不会阻止读者读取。
有没有办法配置postgres,阻止读者读写带锁写的行?
答案 0 :(得分:3)
在postgres 9.5+上有SKIP LOCKED
选项:
如果需要从表中进行SELECT并在事务完成之前保护这些行不被更新,则应指定FOR UPDATE,但如果某些行被锁定,则可以指定SKIP LOCKED以告诉它只是忽略这些行并且只对它可以访问的任何行执行操作。
https://wiki.postgresql.org/wiki/What's_new_in_PostgreSQL_9.5#SKIP_LOCKED
答案 1 :(得分:0)
如果您运行Postgres< = 9.4且NOWAIT
存在,SKIP LOCKED
,则可以选择以下选项。这演示了在CONTINUE
中使用EXIT
和LOOP
以识别下一个可用的未锁定单行。
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;