Тупик на начало транзакции - PullRequest
0 голосов
/ 19 марта 2020

Я использую Postgres 12 с autocommit = off и пытаюсь избежать взаимных блокировок, используя блокировку экспликации. Когда я выполняю:

ROLLBACK;
SELECT * FROM account WHERE id = 12345 FOR UPDATE;

, где id является первичным ключом account. Иногда я захожу в тупик на втором утверждении. Я ожидал бы, что выполнение будет ждать, пока все другие блокировки на линии не будут сняты.

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

Как может возникнуть такая тупик, как указано выше, и как я могу избежать этих тупиков?

Редактировать: Удивительно, но блокировки других процессов, которые показывает мне журнал сервера, также находятся в совершенно разных таблицах, например:

HINT:  See server log for query details.
CONTEXT:  while locking tuple (2892,8) in relation "account"
LOCATION:  DeadLockReport, deadlock.c:1146
STATEMENT:  SELECT * FROM account WHERE id = 197375 FOR UPDATE
LOG:  00000: process 17583 detected deadlock while waiting for ShareLock on transaction 1091990904 after 1000.057 ms
DETAIL:  Process holding the lock: 17438. Wait queue: .
CONTEXT:  while updating tuple (4588,22) in relation "subscription"

Редактировать 2: Я нашел второй тупик в журналах что интересно:

Конфликтный процесс A:

SQL statement "SELECT 1 FROM ONLY "public"."account" x WHERE "id" OPERATOR(pg_catalog.=) $1 FOR KEY SHARE OF x"
SQL statement "WITH inserted_rows AS (
    INSERT INTO payment_token (
        account_id, ..., blocking_time
    )
    VALUES (
        account_id, ..., the_blocking_time
    )
    RETURNING *
)
SELECT * FROM inserted_rows"

Первое утверждение не исходит из моего кода напрямую, а второе является частью хранимой функции.

Конфликт процесс B:

UPDATE account SET address_id = $2, update_time = CURRENT_TIMESTAMP WHERE id = $1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...