sql >> Database >  >> RDS >> Mysql

Rijniveauvergrendeling in Mysql

In plaats van FOR UPDATE gebruik LOCK IN SHARE MODE . FOR UPDATE voorkomt dat andere transacties de rij ook lezen. LOCK IN SHARE MODE staat lezen toe, maar voorkomt updaten.

Referentie:MySQL-handleiding

------ sessie 1

START TRANSACTION;
SELECT * FROM test WHERE t=1 LOCK IN SHARE MODE;
UPDATE test SET NAME='irfandd' WHERE t=2;
COMMIT;

----- sessie 2 (die niet meer wordt geblokkeerd :) )

START TRANSACTION;
UPDATE test SET NAME='irfandd' WHERE t=4;
COMMIT;

Bijwerken:

Realiseren dat de tabel geen index heeft op t , ik heb de volgende uitleg:

Ten eerste vergrendelt transactie T1 de rij 1 in SELECT * FROM test WHERE t=1 FOR UPDATE

Vervolgens probeert transactie T2 UPDATE test SET NAME='irfandd' WHERE t=4 uit te voeren . Om erachter te komen welke rij(en) worden beïnvloed, moet het alle rijen scannen, inclusief rij 1 . Maar dat is vergrendeld, dus T2 moet wachten tot T1 klaar is. Als er een soort index is, de WHERE t=4 kan de index gebruiken om te beslissen of rij 1 bevat t=4 of niet, dus u hoeft niet te wachten.

Optie 1: voeg een index toe op test.t zodat uw update het kan gebruiken.

Optie 2: gebruik LOCK IN SHARE MODE , die alleen bedoeld is om een ​​leesvergrendeling te plaatsen. Helaas zorgt deze optie voor een impasse. Interessant is dat de T2-transactie wordt uitgevoerd (rij 4) en T1 mislukt (rij 2). Het lijkt erop dat T1 read-locks rij 4 ook, en aangezien T2 het wijzigt, mislukt T1 vanwege het transactie-isolatieniveau (HERHAALBAAR LEZEN standaard ). De uiteindelijke oplossing zou zijn om te spelen met Transactie-isolatieniveaus , met behulp van READ UNCOMMITTED of READ COMMITTED transactieniveaus.

De eenvoudigste is Optie 1 , IMHO, maar het is aan jouw mogelijkheden.



  1. MySQL-database onder versiebeheer zetten?

  2. Het negeren van apostrofs in mysql-zoekopdrachten

  3. mysql-equivalente gegevenstypen

  4. pas pager aan in psql