sql >> Database >  >> RDS >> Mysql

Moet SELECT... FOR UPDATE altijd ORDER BY bevatten?

Uw voorbeeld in uw vraag laat zien dat de volgorde van vergrendeling afhangt van de toegangsmethode. Dit toegangspad wordt niet direct bepaald door de ORDER BY-clausule van de query, er zijn veel factoren die dit toegangspad kunnen beïnvloeden. Daarom kunt u een impasse niet voorkomen door alleen een ORDER BY toe te voegen, omdat u nog steeds twee verschillende toegangspaden kunt hebben. Door je testcase uit te voeren met de volgorde door en de sessieparameters te wijzigen, kon ik ervoor zorgen dat twee sessies een ORA-60 tegenkwamen met dezelfde vraag.

Als er voor de betrokken sessies geen andere vergrendeling in behandeling is, worden de rijen in dezelfde volgorde . vergrendeld in alle sessies voorkomt u impasses, maar hoe kunt u deze opdracht op betrouwbare wijze forceren? Merk op dat dit hoe dan ook dit zeer speciale geval van een impasse zou voorkomen. U kunt nog steeds impasses krijgen met meerdere zoekopdrachten in elke sessie of verschillende plannen.

In de praktijk is dit geval heel bijzonder en zou het toch niet vaak moeten gebeuren:als je je zorgen maakt over impasses, denk ik nog steeds dat er eenvoudigere methoden zijn om ze te voorkomen.

De eenvoudigste manier om een ​​impasse te voorkomen, is door FOR UPDATE NOWAIT . te gebruiken of FOR UPDATE WAIT X (hoewel WAIT X nog steeds een impasse kan veroorzaken met waarden van X die superieur zijn aan het deadlock-detectiemechanisme, momenteel 3 seconden vanaf 11g geloof ik -- bedankt @APC voor de correctie).

Met andere woorden, beide transacties zouden moeten vragen:geef me die rijen en vergrendel ze, maar als een andere gebruiker al een blokkering heeft, krijg je een foutmelding in plaats van voor onbepaalde tijd te wachten. Het is het oneindige wachten dat voor impasses zorgt.

In de praktijk zou ik zeggen dat de meeste toepassingen met echte gebruikers liever onmiddellijk een foutmelding krijgen dan dat een transactie voor onbepaalde tijd moet wachten tot een andere transactie is voltooid. Ik zou FOR UPDATE . overwegen zonder NOWAIT alleen voor niet-kritieke batchtaken.



  1. Hoe controleer ik de NLS_LANG van de client?

  2. De 8 meest populaire databases

  3. SQL RENAME TABLE-opdracht

  4. Vagrant port forwarding voor Mysql