【问题标题】:Lock table row from data modifying从数据修改中锁定表行
【发布时间】:2016-01-20 14:19:43
【问题描述】:
CREATE TABLE t1 (
  id serial int,
  col text
);

insert into t1(col) values('old_value');

现在,我需要锁定此表以防止数据修改,而下面的 plsql 块正在运行

DO $$
  declare 
     res1 TEXT;
     res2 TEXT;
  BEGIN 
        --PERFORM pg_advisory_lock( )  
        select col from t1 where id = 1 into  res1;
        FOR i in 1..2000000000 LOOP
           -- this is just for waiting several second
        END LOOP;
        select col from t1 where id = 1 into  res2;
        RAISE NOTICE '% - %', res1, res2;
        --PERFORM pg_advisory_unlock( )  
  END;
  $$ LANGUAGE PLPGSQL

所以当这个块运行时,我运行其他查询:

update t1 SET col = 'new_value' where id = 1;

当运行 plsql 块未完成时,此查询立即生效并更新行。

我需要相反,我需要更新不工作并等待,而 plsql 块运行。

我想pg_advisory_lock()pg_advisory_unlock() 会有所帮助,但是如何使用,我不明白,这些功能的关键参数是什么,我不明白。

而且也不确定这些功能是否会起作用。

任何帮助将不胜感激。

【问题讨论】:

    标签: database postgresql plpgsql postgresql-9.4


    【解决方案1】:

    您希望select col from t1 where id = 1 FOR UPDATE into res1; 获得锁,因此整个块应如下所示:

    DO $$ declare res1 TEXT; res2 TEXT; BEGIN --PERFORM pg_advisory_lock( )
    select col from t1 where id = 1 into FOR UPDATE res1; FOR i in 1..2000000000 LOOP -- this is just for waiting several second END LOOP; select col from t1 where id = 1 into res2; RAISE NOTICE '% - %', res1, res2; --PERFORM pg_advisory_unlock( )
    END; $$ LANGUAGE PLPGSQL

    http://www.postgresql.org/docs/9.4/static/explicit-locking.html

    【讨论】:

      【解决方案2】:

      您可以在SELECT 子句中显式锁定事务中的行:

      DO $$
        DECLARE
           res1 TEXT;
           res2 TEXT;
        BEGIN 
          SELECT col INTO res1 FROM t1 WHERE id = 1 FOR SHARE;
          pg_sleep(5); -- Sleep 5 seconds
          SELECT col INTO res2 FROM t1 WHERE id = 1;
          RAISE NOTICE '% - %', res1, res2;
        END
      $$ LANGUAGE plpgsql;
      

      使用FOR SHARE 子句而不是FOR UPDATE 允许其他会话读取数据,但不更新。

      【讨论】:

      • 谢谢,现在我测试了FOR UPDATE也允许读取数据,例如我可以做select。你的意思是:“使用 FOR SHARE 子句而不是 FOR UPDATE 来允许其他会话读取数据,但不更新。”
      • FOR SHARE锁比FOR UPDATE弱,基本和其他表的主外键使用有关。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-19
      • 1970-01-01
      相关资源
      最近更新 更多