ВЫБРАТЬ ДЛЯ ОБНОВЛЕНИЯ необходимо в CTE для ОБНОВЛЕНИЯ? - PullRequest
0 голосов
/ 07 ноября 2018

В PostgreSQL 9.6 необходимо ли приведенное ниже условие FOR UPDATE в этом CTE?

CREATE OR REPLACE FUNCTION next_job()
    RETURNS json
    LANGUAGE 'sql'

AS $BODY$

    WITH thejob AS (
        SELECT   jobs.*, company.*
        FROM     (
            select * from jobs 
            WHERE NOT EXISTS (SELECT * from jobs AS j2 where jobs.platform = j2.platform and jobs.project = j2.project AND start > now() - interval '1 hour')
            order by priority, account_priority, job_id 
            limit 1) jobs
        LEFT OUTER JOIN company
            ON jobs.company_id = company.id
        , enabled
        WHERE enabled.status IS TRUE
        FOR UPDATE of jobs
    )
    UPDATE jobs
    SET    start = now() 
    FROM   thejob
    WHERE  jobs.job_id = thejob.job_id
    RETURNING json_build_object('job_id', jobs.job_id, 'platform', jobs.platform, 'project', jobs.project, 'firstSeen', thejob.first_seen);

$BODY$;

Цель блокировки состоит в том, чтобы гарантировать, что задание выполняется только одним работником за раз (что, кажется, работает должным образом), но я вижу случайные тупики при вызове этой функции и задаюсь вопросом, является ли моя явная блокировка потенциально вызывающие проблемы.

WHERE NOT EXISTS означает, что один и тот же проект не будет запущен дважды, если он не истек через 1 час.

1 Ответ

0 голосов
/ 07 ноября 2018

Поскольку задействована только одна строка, CTE кажется ненужным. Это имеет смысл, только если вы хотите обновить несколько строк и заблокировать их в определенном порядке, чтобы избежать взаимоблокировок.

Так как запрос заблокирует только одну строку jobs, он не может заблокировать что-либо сам с собой.

В той же транзакции чаще всего присутствуют другие операторы изменения данных, которые вместе с отображаемым оператором создают тупик.

Помните, что блокировки удерживаются до конца транзакции!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...