繁体   English   中英

PostgreSQL:如何使更新可从其他事务中读取,而第一个事务未完成

[英]PostgreSQL: How to make updates readable from other transactions while first transaction not finished

我做简单的时间表服务。

一张工作表

CREATE TABLE system_jobs (
  id bigserial,
  job_time timestamp without time zone,
  job_function text,
  run_on text,
  CONSTRAINT system_jobs_pri PRIMARY KEY (id)
)

多个JAVA守护程序选择job_time < now()所有行并执行job_function (将其id作为参数传递)

job_function示例

CREATE OR REPLACE FUNCTION public.sjob_test(in_id bigint)
  RETURNS text AS
$BODY$DECLARE
    utc timestamp without time zone;
BEGIN
    utc := timezone('UTC', now());

    -- This changes not avail from other transactions
    UPDATE system_jobs SET run_on='hello' WHERE id = in_id;

    PERFORM pl_delay(60); -- Delay 1 minute

    UPDATE system_jobs SET job_time = now() + interval '10 seconds', run_on = '' WHERE id = in_id;

    RETURN 'done';
END;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

在60秒延迟之前的内部函数中,我更新了run_on字段,并在延迟之后将其重置。

我希望run_on在延迟(60秒)内包含“ hello”,并且可以从其他事务中读取,但事实并非如此。

我的任务-防止由不同的JAVA守护进程同时执行相同的job_function 我要在执行前检查run_on

我阅读了许多有关交易级别的文档和博客,但是我不知道如何在实践中使用它。

如何配置函数或表或外部进程以允许其他事务看到此更改?

PostgreSQL不支持脏读。 请参阅PostgreSQL文档

PostgreSQL的Read Uncommitted模式的行为类似于Read Committed。 这是因为这是将标准隔离级别映射到PostgreSQL的多版本并发控制体系结构的唯一明智的方法。

但是看起来有一个变通办法,称为自动交易,可能对您没有帮助。 至少有两种方法可以实现它。 在此处此处查看更多信息。

使用这些自主事务,您可以在函数中提交run_on的更改,以便其他事务能够读取它。

仅有的一种方法-通过dblink。 就像是:

PERFORM dblink('your server config', 'UPDATE ...');

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM