Един от начините за справяне с блокировките е да имате механизъм за повторен опит, който изчаква произволен интервал и се опитва да изпълни транзакцията отново. Случайният интервал е необходим, така че сблъскващите се транзакции да не се сблъскват непрекъснато една с друга, причинявайки това, което се нарича заключване на живо - нещо още по-неприятно за отстраняване на грешки. Всъщност повечето сложни приложения ще се нуждаят от такъв механизъм за повторен опит рано или късно, когато трябва да се справят с грешки при сериализиране на транзакции.
Разбира се, ако можете да определите причината за безизходицата, обикновено е много по-добре да я отстраните или ще да се върна да те ухапя. За почти всички случаи, дори когато условието за блокиране е рядко, малкото пропускателна способност и кодиране, за да поставите ключалките в детерминистичен ред или да получите повече едрозърнести брави, си заслужава, за да избегнете случайното голямо забавяне и внезапното срив на производителността при мащабиране на едновременност.
Когато последователно получавате две инструкции INSERT блокиране, това най-вероятно е проблем с уникална поръчка за вмъкване на индекс. Опитайте например следното в два командни прозореца на psql:
Thread A | Thread B
BEGIN; | BEGIN;
| INSERT uniq=1;
INSERT uniq=2; |
| INSERT uniq=2;
| block waiting for thread A to commit or rollback, to
| see if this is an unique key error.
INSERT uniq=1; |
blocks waiting |
for thread B, |
DEADLOCK |
V
Обикновено най-добрият курс на действие за разрешаване на това е да се разберат родителските обекти, които пазят всички подобни транзакции. Повечето приложения имат един или два основни обекта, като потребители или акаунти, които са добри кандидати за това. След това всичко, от което се нуждаете, е всяка транзакция да получи ключалките на основния обект, до който се докосва, чрез ИЗБОР ... ЗА АКТУАЛИЗИРАНЕ. Или ако докоснете няколко, вземете ключалки за всички, но в един и същи ред всеки път (подреждането по първичен ключ е добър избор).