Postgres写/读锁

时间:2016-11-11 18:46:18

标签: database postgresql postgresql-9.2

我有多线程JEE应用程序,它运行SELECT FOR UPDATE LIMIT 1;在每个事务中使用WHERE子句和Update行查询表,这会创建行级写锁,不会阻止读者读取。

有没有办法配置postgres,阻止读者读写带锁写的行?

2 个答案:

答案 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中使用EXITLOOP以识别下一个可用的未锁定单行。

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;