【问题标题】:beginning isolation level in postgresql在 postgresql 中开始隔离级别
【发布时间】:2021-07-08 01:19:07
【问题描述】:

我在plpgsql中有如下声明:

CREATE OR REPLACE FUNCTION json_update (mdata JSON) RETURNS void AS $$
          DECLARE
            mdata JSON = mdata;
              mRecord record;
          BEGIN
            BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
              SELECT 
                 COALESCE(searches, 0) AS searched_quantity,
                 COALESCE(event, '2030-06-29') AS event_date,
              INTO mRecord 
                  FROM json_populate_record(NULL::my_app.app_report, mdata::JSON);
                  
              --here I also do some lengthy write operations and some calculation taking above data
            COMMIT;
         END;
$$ LANGUAGE plpgsql;

SELECT * FROM json_update('{"event":"2021-07-07","searches":10}');

我在以下行中遇到语法错误:BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;

据我所知,这就是我们在存储过程之外设置事务级别的方式,如果我在psql 命令行中这样做,语法就很好。顺便说一句,我从pgAdmin 的查询面板执行此操作。

在存储过程中设置事务级别是否有另一种语法?顺便说一句,我已经read this and it doesn't really answer my question.

【问题讨论】:

标签: postgresql


【解决方案1】:

您永远无法控制函数中的事务。如果确实需要在过程代码中提交,则必须使用存储过程。

当程序进入时,一个事务会自动启动,所以你不能启动另一个一个,但是你可以将隔离级别设置为第一个命令:

CREATE OR REPLACE procedure json_update (mdata JSON) AS $$
DECLARE
   mRecord record;
BEGIN
  SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
  SELECT 
     COALESCE(searches, 0) AS searched_quantity,
     COALESCE(event, '2030-06-29') AS event_date
  INTO mRecord 
        FROM json_populate_record(NULL::my_app.app_report, mdata::JSON);
                  
  ... do your work here ...
  COMMIT;
END;
$$ LANGUAGE plpgsql;

更多详情in the manual

【讨论】:

  • 您的意思是“....无法启动另一个”,并发事务会失败吗?我试图得到这样的行为:进入(并行)的第二个事务将等到第一个事务完成
  • 调用过程隐式启动事务,因此您不能(也不需要)在过程开始时启动一个事务。并且可重复读取不会让调用者等待 - 它只会确保过程中的事务在所有语句中看到一致的状态。
  • 那么我该怎么做才能让发送呼叫等待?我尝试使用 'SELECT *.... FOR UPDATE` ,但是,一旦我从多个线程发出请求,它就会给我一个 concurrent threads updating same record 错误
  • by, "...你不能在程序开始的时候开始(也不需要)开始一个",你的意思是第二个事务 取消了吗?
  • 不确定您指的是哪一个事务,但除非您运行回滚或发生错误,否则 Postgres 不会“取消”事务。如果要确保在任何给定时间仅由单个会话执行过程,则需要使用其他工具。隔离级别不适合这种情况。但这是一个完全不同的问题。
猜你喜欢
  • 2014-07-11
  • 2018-11-16
  • 1970-01-01
  • 2021-11-29
  • 1970-01-01
  • 1970-01-01
  • 2018-10-23
  • 2015-08-02
  • 2011-03-31
相关资源
最近更新 更多