Этот дедлок - проявление MVCC, механизма, чтобы несколько пользователей могли работать с БД одновременно.
Визуализировать эту ситуацию можно как перекрестные стрелки в зависимостях
Если мы говорим про postgres, то если ты обновил какую-то запись (кортеж), то неявно получаешь на нее (запись) блокировку. Когда кто-то другой хочет обновить эту же запись, то ждет ее освобождения.
В данном случае (визуализация), 1 процесс выполнял
UPDATE X, Y
а другой
UPDATE Y, X
, т.е. первый взял блокировку сначала на X потом на Y, а другой - сначала на Y потом на X. Первая блокировка успешна, но вторые нет - они уже заняты.
В данном случае, разрешить их нельзя, т.к. оба ждут пока один из них снимет блокировку, но этого не произойдет. Блокировка со строки снимется по окончании транзакции.
Совет про сортировку взят, чтобы привнести единообразие в работу. Грубо говоря, дедлок появляется, когда нет согласованности в работе. Если оба выполнят
UPDATE X, Y
(в таком порядке), то дедлока не будет т.к. один из них сможет взять все блокировки на строки успешно. Поведение второго будет уже зависеть от уровня сериализации:
- Read committed - обновит новые данные
- Другие (repeatable read, serializable) - ошибка выполнения
Это уже детали MVCC в postgres (read uncommitted нет)