3

私はPL/pgSQL関数「interpolate_values」に時間のかかる計算で取り組んでいます。「interpolation_jobs」と呼ばれるテーブルには、すべての関数呼び出しに関する監視情報が含まれており、特定の job_id を持つ関数呼び出しの進行状況は、

SELECT status FROM interpolation_jobs WHERE id = job_id;

列「ステータス」には、「キュー済み」、「実行中」、または「完了」のいずれかの値が含まれています。関数の開始時にステータスが「キュー」から「実行中」に変更され、最後に「完了」に設定されます。

CREATE OR REPLACE FUNCTION interpolate_values (job_id INTEGER)
RETURNS VOID
LANGUAGE plpgsql VOLATILE
AS $$
DECLARE
BEGIN
    EXECUTE 'UPDATE interpolation_jobs
        SET status = ''running'', progress = 0.0
        WHERE id = ' || job_id || ';';

--
-- ... some extensive database computations ...
--

    EXECUTE 'UPDATE interpolation_jobs
        SET status = ''done''
        WHERE id = ' || job_id || ';';

END;
$$;

私の問題は、関数呼び出し中にステータスが更新されないことです。関数呼び出しが戻ると、実際に更新が行われます。そのため、ステータスは「queued」から「done」に直接変わります。台詞

    EXECUTE 'UPDATE interpolation_jobs
        SET status = ''running'', progress = 0.0
        WHERE id = ' || job_id || ';';

影響はありません。

関数呼び出しが戻る前に新しい値にアクセスできるように、PL/pgSQL で値をすぐに更新する可能性はありますか?

ありがとう!

編集:

非同期データベース操作の一般的な問題を理解するのに大いに役立ったすべての回答に感謝します。dblink アプローチは私にとってはうまくいきます。同じデータベースを使用する場合、IP/ポート/ユーザーを指定する必要はありません。

SELECT * FROM current_database() INTO _db_name;
PERFORM dblink_connect('dbname=' || _db_name);
PERFORM dblink_exec('UPDATE interpolation_jobs SET status = ''running'' WHERE id =' || _job_id);

-- 
-- ... some extensive database computations ...
--

PERFORM dblink_exec('UPDATE interpolation_jobs SET status = ''done'' WHERE id =' || _job_id);
PERFORM dblink_disconnect();
4

2 に答える 2