postgresql — Как найти тупик Postgres / PHP в параллельных обновлениях?

Итак, у меня есть онлайн-игра на PHP / PostgreSQL, и один из процессов обновления иногда дает мне тупики, например:

[2016-02-16 06:35:14] app.ERROR: Doctrine \ DBAL \ DBALException: An
возникла исключительная ситуация при выполнении ‘UPDATE PlayerCharacter SET
spotting_distance =?, видимость =? ГДЕ id =? ‘ с параметрами [2167,
20, 128]: SQLSTATE [40P01]: обнаружена взаимоблокировка: 7 ОШИБКА: взаимоблокировка
обнаружена ДЕТАЛИ: Процесс 11691 ожидает ShareLock в транзакции
4173974; заблокирован процессом 11706. Процесс 11706 ожидает ShareLock
по транзакции 4173977; заблокирован процессом 11691. Подсказка: см. сервер
журнал для деталей запроса.

Я попытался просмотреть журналы сервера, но это не помогает.

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

Код обновляет большое количество строк, поэтому я разделил обработку на 6 параллельных процессов, каждый из которых обновляет подмножество общего количества. Другими словами: никакой другой процесс не должен обновлять строку первичным идентификатором 128. Так почему же существует тупик?

Я подозреваю, что а) что-то странное или б) ошибка в моем коде планирования и какой-то другой процесс является обновление строки № 128.

Как я могу узнать, что происходит? Могу ли я убедить Doctrine или Postgres показать мне блокирующую транзакцию? Можно ли как-то сделать транзакцию неблокируемой (поскольку это параллельные процессы, использующие одну и ту же математику, результат должен быть одинаковым в любом случае, и если по какой-то причине это не так, я бы предпочел получить результат, который будет несколько процентов, чем тупик).

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …