我做简单的时间表服务。

带工作的一张桌子

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 documentation


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


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

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

07-24 09:47
查看更多