sql >> Databáze >  >> RDS >> Mysql

Má SELECT ... FOR UPDATE vždy obsahovat ORDER BY?

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.



  1. ukládání dat do databáze pomocí editace textu a tlačítka

  2. Proč nevyužít vestavěné uživatele a oprávnění MySQL pro web?

  3. Jak nastavit kódování pro char sloupce tabulek v django?

  4. 2 způsoby, jak získat počet dní v měsíci v Oracle