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中使用CONTINUEEXIT以便识别下一个可用的解锁单行。

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;