Jedním ze způsobů, jak se vypořádat se zablokováním, je mít mechanismus opakování, který čeká na náhodný interval a pokusí se transakci spustit znovu. Náhodný interval je nezbytný, aby kolidující transakce do sebe neustále nenarážely a nezpůsobovaly to, čemu se říká živý zámek – něco ještě horšího k ladění. Ve skutečnosti bude většina složitých aplikací takový mechanismus opakování dříve nebo později potřebovat, když potřebují zvládnout selhání serializace transakcí.
Samozřejmě, pokud jste schopni určit příčinu uváznutí, je obvykle mnohem lepší ji odstranit, nebo bude vrať se tě kousnout. Téměř ve všech případech, i když je stav uváznutí vzácný, se trocha propustnosti a režie kódování pro získání zámků v deterministickém pořadí nebo získání více hrubozrnných zámků vyplatí, abyste se vyhnuli občasnému velkému zpoždění a náhlému poklesu výkonu. při škálování souběžnosti.
Když se vám trvale zablokují dva příkazy INSERT, je to s největší pravděpodobností problém s jedinečným pořadím vložení indexu. Zkuste například následující ve dvou příkazových oknech 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
Obvykle je nejlepším postupem k vyřešení tohoto problému zjistit nadřazené objekty, které hlídají všechny takové transakce. Většina aplikací má jednu nebo dvě primární entity, jako jsou uživatelé nebo účty, které jsou pro to dobrými kandidáty. Pak vše, co potřebujete, je pro každou transakci získat zámky na primární entitě, které se dotkne, pomocí SELECT ... FOR UPDATE. Nebo pokud se jich dotknete několik, získejte zámky na všechny, ale pokaždé ve stejném pořadí (dobrou volbou je pořadí podle primárního klíče).