Vergrendeling begrijpen
MvCC (Multi-Version Concurrency Control) biedt de juiste gelijktijdigheidsinstellingen voor de meeste scenario's. Als voor een toepassing echter specifieke vergrendelingen nodig zijn waarmee precies wordt bepaald welke rijen worden beïnvloed en met een specifiek vergrendelingsniveau, schakelt u deze verfijnde controle in met expliciete vergrendelingsmodi.
In Azure Database for PostgreSQL zijn er drie typen expliciete vergrendelingen, vergrendelingen op tabelniveau, vergrendelingen op rijniveau en vergrendelingen op paginaniveau. De eerste transactie vraagt om een vergrendeling en, indien geaccepteerd, wordt de aangevraagde vergrendeling de bestaande vergrendeling. Als een andere transactie probeert een vergrendeling op dezelfde gegevens uit te schakelen, wordt de vergrendeling verleend als deze niet conflicteert met de oorspronkelijke transactie.
Twee transacties kunnen bijvoorbeeld op dezelfde gegevens tegelijk query's uitvoeren met een SELECT-instructie. Voor deze aanvragen wordt een ACCESS SHARE-vergrendeling gebruikt en beide zijn toegestaan. In een ander scenario voert een transactie een query uit op gegevens met een SELECT-instructie en een ACCESS SHARE-vergrendeling, maar tegelijkertijd probeert een andere transactie dezelfde tabel te verwijderen. Voor het verwijderen van een tabel is een ACCESS EXCLUSIVE-vergrendeling vereist, die in dit scenario niet zou worden verleend.
Vergrendelingen op tabelniveau
Vergrendelingen op tabelniveau krijgen vergrendelingen voor een hele tabel, zelfs als ze RIJ in hun naam hebben. Het vergrendelen van een hele tabel is mogelijk vereist als de tabel zelf wordt gewijzigd of efficiënter is dan het verwijderen van veel vergrendelingen op rijniveau.
Er zijn acht typen vergrendeling op tabelniveau in Azure Database for PostgreSQL en de SQL-opdrachten die deze typen vergrendelingen verkrijgen zijn:
| Vergrendelingsmodus | Overgenomen door |
|---|---|
| Toegang Delen | SELECT-opdracht |
| RIJSHARE | SELECT FOR UPDATE- en SELECT FOR SHARE-commando's |
| RIJ EXCLUSIEF | Opdrachten BIJWERKEN, VERWIJDEREN en INVOEGEN |
| EXCLUSIEF DELEN | ANALYSEREN, INDEX GELIJKTIJDIG AANMAKEN, STATISTIEKEN MAKEN, COMMENTAAR, GELIJKTIJDIG HERINDEXEREN, sommige ALTER INDEX- en ALTER TABLE-opdrachten, en VACUUM (niet FULL) |
| DELEN | CREATE INDEX-opdracht (niet GELIJKTIJDIG) |
| EXCLUSIEVE RIJDELING | CREATE TRIGGER-opdracht en enkele ALTER TABLE-opdrachten |
| EXCLUSIEF | OPDRACHT GEREALISEERDE WEERGAVE GELIJKTIJDIG VERNIEUWEN |
| EXCLUSIEVE TOEGANG | DROP TABLE, REINDEX, TRUNCATE, CLUSTER, REFRESH MATERIALIZED VIEW (niet GELIJKTIJDIG) opdrachten, de meeste ALTER INDEX- en ALTER TABLE-opdrachten, en VACUUM FULL |
Elk type bestaande vergrendeling blokkeert andere aangevraagde vergrendelingen die worden verkregen. In de volgende tabel ziet u welke vergrendelingen voorkomen dat andere vergrendelingen worden verkregen:
| -- | Bestaande ACCESS SHARE | Bestaande RIJDELING | Bestaande RIJ EXCLUSIEF | Bestaande UPDATE DELEN EXCLUSIEF | Bestaande gedeelde bestand | Bestaande SHARE ROW EXCL | Bestaande Exclusief | Bestaande Toegang Exclusief |
|---|---|---|---|---|---|---|---|---|
| Aangevraagde toegangsaandelen | Geblokkeerd | |||||||
| De aangevraagde DEEL VAN DE RIJ | Geblokkeerd | Geblokkeerd | ||||||
| Aangevraagde Rijexclusiviteit | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | ||||
| Exclusieve update voor aandelen aangevraagd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | |||
| Aangevraagde Aandeel | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | |||
| AANGEVRAAGDE RIJDEEL EXCLUSIEF | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | ||
| Exclusief aangevraagd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | |
| AANGEVRAAGDE EXCLUSIEVE TOEGANG | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd |
Vergrendelingen op rijniveau
Vergrendelingen op rijniveau zijn gedetailleerder en hebben alleen invloed op een andere transactie die toegang heeft tot dezelfde rij. Dit vergrendelingstype verbetert gelijktijdigheid, maar het verkrijgen en verwijderen van veel vergrendelingen heeft een negatieve invloed op de prestaties. Vergrendelingen op rijniveau worden automatisch verkregen door PostgreSQL en worden niet handmatig toegepast.
Er zijn vier typen vergrendeling op rijniveau in Azure Database for PostgreSQL en deze worden verkregen, afhankelijk van welke andere vergrendelingstypen moeten worden geblokkeerd:
| -- | Bestaande FOR KEY SHARE | Bestaande FOR SHARE | Bestaande VOOR GEEN SLEUTELWIJZIGING | Bestaand VOOR UPDATE |
|---|---|---|---|---|
| Aangevraagd VOOR SLEUTELSHARE | Geblokkeerd | |||
| Aangevraagd VOOR DELEN | Geblokkeerd | Geblokkeerd | ||
| Aangevraagd VOOR GEEN SLEUTELUPDATE | Geblokkeerd | Geblokkeerd | Geblokkeerd | |
| Aangevraagd voor update | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd |
Vergrendelingen op paginaniveau
Vergrendelingen op paginaniveau zijn van invloed op een pagina met gegevens, die doorgaans uit meerdere rijen bestaan. Hoewel PostgreSQL-processen gebruikmaken van vergrendelingen op paginaniveau, vereisen toepassingsontwikkelaars dit type vergrendeling doorgaans niet.
Vergrendelingen handmatig toepassen en huidige vergrendelingen weergeven
Als u handmatig een vergrendeling op tabelniveau wilt toepassen, kunt u de opdracht LOCK gebruiken met de vereiste vergrendelingsmodus. De opdracht LOCK moet zich binnen een transactie bevinden en de vergrendelingen worden vrijgegeven wanneer de transactie is voltooid. Voorbeeld:
BEGIN TRANSACTION;
LOCK TABLE humanresources.department IN ROW EXCLUSIVE MODE;
COMMIT;
Gebruik pg_locks om vergrendelingen weer te geven die momenteel in de database zijn opgeslagen. Als u bijvoorbeeld alle huidige vergrendelingen wilt weergeven, gebruikt u de volgende opdracht:
SELECT * FROM pg_locks;