MySQL
MySQL LOCK TABELL
Sök…
Syntax
LOCK TABLES tabellnamn [LÄS | SKRIVA]; // Låsbord
LÅSBORDAR; // Lås upp tabeller
Anmärkningar
Låsning används för att lösa samtidighetsproblem. Låsning krävs endast när du kör en transaktion, som först läser ett värde från en databas och senare skriver in det till databasen. Lås krävs aldrig för fristående insättning, uppdatering eller radering.
Det finns två typer av lås tillgängliga
LÄS LÅS - när en användare bara läser från en tabell.
SKRIV LÅS - när en användare gör både läsning och skrivning till ett bord.
När en användare har ett WRITE LOCK
på ett bord, kan inga andra användare läsa eller skriva till den tabellen. När en användare har ett READ LOCK
på ett bord kan andra användare också läsa eller hålla ett READ LOCK
, men ingen användare kan skriva eller hålla ett WRITE LOCK
på det bordet.
Om standardlagringsmotorn är InnoDB använder MySQL automatiskt radnivålåsning så att flera transaktioner kan använda samma tabell samtidigt för att läsa och skriva, utan att låta varandra vänta.
För alla andra lagringsmotorer än InnoDB använder MySQL tabelllåsning.
För mer information om bordlås Se här
Mysql Locks
Bordslås kan vara ett viktigt verktyg för ENGINE=MyISAM
, men är sällan användbara för ENGINE=InnoDB
. Om du frestas att använda bordslås med InnoDB bör du tänka om hur du arbetar med transaktioner.
MySQL gör det möjligt för klientsessioner att förvärva tabelllås uttryckligen i syfte att samarbeta med andra sessioner för åtkomst till tabeller, eller för att förhindra andra sessioner från att ändra tabeller under perioder då en session kräver exklusiv åtkomst till dem. En session kan skaffa eller släppa lås bara för sig själv. En session kan inte skaffa lås för en annan session eller släppa lås som innehas av en annan session.
Lås kan användas för att emulera transaktioner eller för att få högre hastighet vid uppdatering av tabeller. Detta förklaras mer detaljerat senare i det här avsnittet.
Kommando: LOCK TABLES table_name READ|WRITE;
du kan endast tilldela en låstyp till ett enda bord;
Exempel (LÄS LÅS):
LOCK TABLES table_name READ;
Exempel (SKRIV LÅS):
LOCK TABLES table_name WRITE;
För att se låset tillämpas eller inte, använd följande kommando
SHOW OPEN TABLES;
För att spola / ta bort alla lås, använd följande kommando:
UNLOCK TABLES;
EXEMPEL:
LOCK TABLES products WRITE:
INSERT INTO products(id,product_name) SELECT id,old_product_name FROM old_products;
UNLOCK TABLES;
Ovan exemplet kan inte någon extern anslutning skriva någon data till produkttabellen förrän du låser upp tabellprodukten
EXEMPEL:
LOCK TABLES products READ:
INSERT INTO products(id,product_name) SELECT id,old_product_name FROM old_products;
UNLOCK TABLES;
Ovan exemplet kan inte någon extern anslutning läsa data från produkttabellen förrän du låser upp tabellprodukten
Låsa radnivå
Om tabellerna använder InnoDB använder MySQL automatiskt radnivålåsning så att flera transaktioner kan använda samma tabell samtidigt för läsning och skrivning, utan att få varandra att vänta.
Om två transaktioner som försöker modifiera samma rad och båda använder radnivålåsning, väntar en av transaktionerna på att den andra ska slutföras.
Låsen på radnivå kan också erhållas genom att använda SELECT ... FOR UPDATE
för varje rader som förväntas ändras.
Tänk på två anslutningar för att förklara radnivålåsning i detalj
Anslutning 1
START TRANSACTION;
SELECT ledgerAmount FROM accDetails WHERE id = 1 FOR UPDATE;
I anslutning 1, radnivålås erhållet med SELECT ... FOR UPDATE
.
Anslutning 2
UPDATE accDetails SET ledgerAmount = ledgerAmount + 500 WHERE id=1;
När någon försöker uppdatera samma rad i anslutning 2 kommer den att vänta på anslutning 1 för att avsluta transaktionen eller felmeddelandet visas enligt inställningen innodb_lock_wait_timeout
, som är standard till 50 sekunder.
Error Code: 1205. Lock wait timeout exceeded; try restarting transaction
För att visa detaljer om detta lås, kör SHOW ENGINE INNODB STATUS
---TRANSACTION 1973004, ACTIVE 7 sec updating
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 360, 1 row lock(s)
MySQL thread id 4, OS thread handle 0x7f996beac700, query id 30 localhost root update
UPDATE accDetails SET ledgerAmount = ledgerAmount + 500 WHERE id=1
------- TRX HAS BEEN WAITING 7 SEC FOR THIS LOCK TO BE GRANTED:
Anslutning 2
UPDATE accDetails SET ledgerAmount = ledgerAmount + 250 WHERE id=2;
1 row(s) affected
Men vid uppdatering av någon annan rad i anslutning 2 kommer att köras utan fel.
Anslutning 1
UPDATE accDetails SET ledgerAmount = ledgerAmount + 750 WHERE id=1;
COMMIT;
1 row(s) affected
Nu släpps radlåset eftersom transaktionen begås i anslutning 1.
Anslutning 2
UPDATE accDetails SET ledgerAmount = ledgerAmount + 500 WHERE id=1;
1 row(s) affected
Uppdateringen utförs utan fel i anslutning 2 efter att anslutning 1 släppte radlåset genom att avsluta transaktionen.