2017-05-05 80 views
0

我做簡單的日程安排服務。PostgreSQL:如何在首次交易未完成時使其他交易可讀取更新

一個有工作表

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 60之前(通過他們的id作爲參數)

工作職務樣品

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; 

內部功能秒延遲我更新run_on字段,並在延遲後重置。

我希望run_on包含'你好',而延遲(60秒),並可用於從其他交易中讀取,但事實並非如此。

我的任務 - 防止同時執行不同的JAVA守護進程相同的job_function。我想在執行前檢查run_on

我讀了很多關於交易級別的文檔和博客,但我不明白我怎麼能在實踐中使用它。

如何配置我的函數或表或外部進程以允許其他事務看到此更改?

+0

不可能。 Postgres永遠不會允許髒讀(未提交的更改) –

回答

1

PostgreSQL不支持髒讀。請參閱PostgreSQL documentation

PostgreSQL的Read Uncommitted模式的行爲與Read Committed類似。這是因爲它是將標準隔離級別映射到PostgreSQL的多版本併發控制體系結構的唯一明智方式。

但看起來像有一種解決方法稱爲自主事務,可能會幫助你。至少有兩種方法來實現它。查看更多信息herehere

使用這些自治事務,您可以在您的函數內提交更改run_on,以便其他事務將能夠讀取它。

0

只有一種方法可以做到 - 通過dblink。例如:

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