Váš příklad ve vaší otázce ukazuje, že pořadí zamykání závisí na metodě přístupu. O této přístupové cestě nerozhoduje přímo klauzule ORDER BY dotazu, existuje mnoho faktorů, které mohou tuto přístupovou cestu ovlivnit. Proto nemůžete zabránit uváznutí pouhým přidáním ORDER BY, protože stále můžete mít dvě odlišné přístupové cesty. Ve skutečnosti spuštěním vašeho testovacího případu s objednávkou a změnou parametrů relace jsem byl schopen způsobit, že dvě relace naběhly do ORA-60 se stejným dotazem.
Pokud příslušné relace nemají žádné další nevyřízené uzamčení, řádky se uzamknou ve stejném pořadí ve všech relacích zabrání uváznutí, ale jak můžete tento příkaz spolehlivě vynutit? Všimněte si, že by to stejně zabránilo pouze tomuto velmi zvláštnímu případu uváznutí. Stále se můžete dostat do uváznutí s více dotazy v každé relaci nebo s různými plány.
V praxi je tento případ opravdu výjimečný a stejně by se neměl stávat často:pokud se obáváte uváznutí, stále si myslím, že existují jednodušší způsoby, jak jim předejít.
Nejjednodušší způsob, jak zabránit zablokování, je použít buď FOR UPDATE NOWAIT
nebo FOR UPDATE WAIT X
(ačkoli WAIT X může stále vyvolat uváznutí s hodnotami X lepšími než mechanismus detekce uváznutí, v současné době věřím 3 sekundy od 11 g -- díky @APC
pro opravu).
Jinými slovy, obě transakce by se měly zeptat:dejte mi ty řádky a zamkněte je, ale pokud jiný uživatel již má zámek, vrátí chybu místo čekání donekonečna. Je to nekonečné čekání, které způsobuje uváznutí.
V praxi bych řekl, že většina aplikací se skutečnými uživateli by raději okamžitě obdržela chybu, než aby transakce donekonečna čekala na dokončení další transakce. Zvažoval bych FOR UPDATE
bez NOWAIT
pouze pro nekritické dávkové úlohy.