Postgres 写/读锁

Posted

技术标签:

【中文标题】Postgres 写/读锁【英文标题】:Postgres Write/Read Lock 【发布时间】:2016-11-11 18:46:18 【问题描述】:

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

有什么办法可以配置 postgres,阻止读者用写锁读取行?

【问题讨论】:

【参考方案1】:

在 postgres 9.5+ 上有 SKIP LOCKED 选项:

如果您需要从表中 SELECT 并保护这些行在事务完成之前不被更新,您可以指定 FOR UPDATE,但如果某些行被锁定,您可以指定 SKIP LOCKED 来告诉它简单地忽略这些行并且只需对它可以访问的任何行执行操作。

https://wiki.postgresql.org/wiki/What's_new_in_PostgreSQL_9.5#SKIP_LOCKED

【讨论】:

【参考方案2】:

如果您正在运行 Postgres 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;

【讨论】:

以上是关于Postgres 写/读锁的主要内容,如果未能解决你的问题,请参考以下文章

创建 postgres 用户

两列中的Postgres不同查询

linux安装配置postgres及使用dblink

来自多个表的 Postgres/netezza 多重连接

Postgres-XL 数据库

如何在 Postgres 中对数组列使用 BETWEEN 条件?