Förstå låsning

Slutförd

Multi-Version Concurrency Control (MVCC) tillhandahåller lämpliga samtidighetsinställningar för de flesta scenarier. Men om ett program kräver specifika lås som styr exakt vilka rader som påverkas och med en specifik låsnivå, aktiverar explicita låslägen den här detaljerade kontrollen.

I Azure Database for PostgreSQL finns det tre typer av explicit lås, lås på tabellnivå, radnivålås och lås på sidnivå. Den initiala transaktionen ber om ett lås, och om det accepteras blir det begärda låset det existerande låset. Om en annan transaktion försöker ta ut ett lås på samma data beviljas låset om det inte står i konflikt med den ursprungliga transaktionen.

Två transaktioner kan till exempel köra frågor mot samma data samtidigt med en SELECT-instruktion. Dessa begäranden skulle använda ett ACCESS SHARE-lås och båda skulle tillåtas. I ett annat scenario hämtar en transaktion data med en SELECT-instruktion och ett ACCESS SHARE-lås, men samtidigt försöker en annan transaktion ta bort samma tabell. Att ta bort en tabell kräver ett EXKLUSIV TILLGÅNG-lås, som inte skulle beviljas i det här scenariot.

Lås på tabellnivå

Lås på tabellnivå förvärvar lås på en hel tabell, även om de har ordet RAD i sitt namn. Det kan krävas att du låser en hel tabell om själva tabellen ändras eller om den är mer effektiv än att ta bort många lås på radnivå.

Det finns åtta typer av lås på tabellnivå i Azure Database for PostgreSQL och SQL-kommandona som hämtar dessa typer av lås är:

Låsläge Förvärvad av
DELAD ÅTKOMST SELECT-kommando
RADSAMARBETE VÄLJ FÖR UPPDATERING och VÄLJ FÖR DELNING-kommandon
RADEN EXKLUSIV Kommandon "UPDATE", "DELETE" och "INSERT"
EXKLUSIV UPPDATERING ANALYSERA, SKAPA INDEX SAMTIDIGT, SKAPA STATISTIK, KOMMENTERA, INDEXERA OM SAMTIDIGA kommandon, vissa ALTER INDEX- och ALTER TABLE-kommandon och VACUUM (inte FULLSTÄNDIG)
DELA KOMMANDOT CREATE INDEX (inte SAMTIDIGT)
DELA RAD EXKLUSIVT Kommandot CREATE TRIGGER och vissa ALTER TABLE-kommandon
EXKLUSIV UPPDATERA KOMMANDOT MATERIALISERAD VY SAMTIDIGT
EXKLUSIV TILLGÅNG Kommandon DROP TABLE, REINDEX, TRUNCATE, CLUSTER, REFRESH MATERIALIZED VIEW (inte SAMTIDIGT), de flesta ALTER INDEX- och ALTER TABLE-kommandon och VACUUM FULL

Varje typ av befintligt lås blockerar andra begärda lås som hämtas. I följande tabell visas vilka lås som hindrar andra lås från att hämtas:

-- Befintlig ÅTKOMSTDELNING Befintlig raddelning Befintlig RAD EXKLUSIV EXKLUSIV UPPDATERING FÖR BEFINTLIGA AKTIER Befintlig RESURS Exklusive för befintlig DELNINGSRAD Befintlig EXKLUSIV Befintlig ÅTKOMST EXKLUSIV
Begärd ÅTKOMSTDELNING Blockerad
Begärd RADRESURS Blockerad Blockerad
Begärd rad exklusiv Blockerad Blockerad Blockerad Blockerad
BEGÄRD EXKLUSIV AKTIEUPPDATERING Blockerad Blockerad Blockerad Blockerad Blockerad
Begärd RESURS Blockerad Blockerad Blockerad Blockerad Blockerad
BEGÄRD EXKLUSIV RADLÅS Blockerad Blockerad Blockerad Blockerad Blockerad Blockerad
Begärd exklusiv Blockerad Blockerad Blockerad Blockerad Blockerad Blockerad Blockerad
BEGÄRD ÅTKOMST EXKLUSIV Blockerad Blockerad Blockerad Blockerad Blockerad Blockerad Blockerad Blockerad

Lås på radnivå

Lås på radnivå är mer detaljerade och påverkar bara en annan transaktion som har åtkomst till samma rad. Den här låstypen förbättrar samtidigheten, men att hämta och släppa många lås påverkar prestanda negativt. Lås på radnivå hämtas automatiskt av PostgreSQL och tillämpas inte manuellt.

Det finns fyra typer av lås på radnivå i Azure Database for PostgreSQL och de hämtas beroende på vilka andra låstyper som måste blockeras:

-- Befintlig FÖR NYCKELDELNING Befintlig FÖR ANDEL Befintlig FÖR INGEN NYCKELUPPDATERING Befintlig för uppdatering
Begärd FÖR DELNING NYCKEL Blockerad
Begärd FÖR DELNING Blockerad Blockerad
Begärd UTAN NYCKELUPPDATERING Blockerad Blockerad Blockerad
Begärd FÖR UPPDATERING Blockerad Blockerad Blockerad Blockerad

Lås på sidnivå

Lås på sidnivå påverkar en sida med data, som vanligtvis består av flera rader. Även om PostgreSQL-processer använder lås på sidnivå kräver programutvecklare vanligtvis inte den här typen av lås.

Tillämpa lås manuellt och visa aktuella lås

Om du vill tillämpa ett lås på tabellnivå manuellt kan du använda kommandot LOCK med det låsläge som krävs. LÅS-kommandot måste finnas i en transaktion och låsen frigörs när transaktionen är klar. Till exempel:

BEGIN TRANSACTION;
LOCK TABLE humanresources.department IN ROW EXCLUSIVE MODE;
COMMIT;

Om du vill visa lås som för närvarande finns i databasen, använd pg_locks. Om du till exempel vill visa alla aktuella lås använder du följande kommando:

SELECT * FROM pg_locks;