PostgreSQL wordt geleverd met solide, beproefde functies waarmee u precies kunt definiëren wat er moet gebeuren als meerdere clients tegelijkertijd dezelfde gegevens proberen bij te werken. Een daarvan is het isolatieniveau van transacties.
Lees verder om meer te weten te komen over hoe transactie-isolatie werkt in PostgreSQL.
Transacties en isolatieniveau
Transacties zijn de fundamentele manier om gegevens in een RDBMS te muteren. Moderne RDBMS staat toe dat meer dan één transactie gelijktijdig wordt uitgevoerd en wordt daarom geleverd met een verscheidenheid aan tools - sommige standaard, sommige RDBMS-specifiek - voor applicatieontwikkelaars om te specificeren hoe hun transacties wel of niet moeten interageren met andere transacties.
Transactie-isolatieniveaus en pessimistische sloten zijn twee van dergelijke hulpmiddelen. Hoewel deze noodzakelijk zijn voor gegevensintegriteit en prestaties, zijn ze helaas niet intuïtief om te begrijpen of te gebruiken.
Het isolatieniveau van een transactie, in PostgreSQL, kan een van de volgende zijn:
- Lees Toegewijd
- Herhaalbaar lezen
- Serializeerbaar
Elke transactie heeft zijn isolatieniveau ingesteld op een van deze wanneer deze wordt gemaakt. Het standaardniveau is "lees vastgelegd".
Merk op dat de SQL-standaard ook "read uncommitted" definieert, wat niet wordt ondersteund in Postgres. U moet het dichtstbijzijnde, hogere niveau van "read commit" gebruiken.
Laten we eens kijken wat deze niveaus betekenen.
Lezen Toegewijd
Wat gebeurt er als de ene (onvoltooide) transactie rijen in een tabel invoegt en de andere (ook onvoltooide) transactie alle rijen in de tabel probeert te lezen? Als de tweede transactie de rijen kan zien die door de eerste zijn ingevoegd, wordt dat lezen een dirty read genoemd - omdat de eerste transactie kan worden teruggedraaid en de tweede transactie "fantoom" -rijen zou hebben gelezen die nooit hebben bestaan.
De lees vastgelegd isolatieniveau garandeert dat vuile lezingen nooit zullen gebeuren. Hier is een voorbeeld:
Zoals u kunt zien, kon de tweede transactie de nog niet vastgelegde gegevens van de eerste transactie niet lezen. In PostgreSQL is het niet mogelijk om het isolatieniveau tot onder dit niveau te verlagen, zodat vuil lezen is toegestaan.
Herhaalbare read
Nog een ander probleem is dat van niet-herhaalbare reads. Dit gebeurt wanneer een transactie een rij leest en deze iets later opnieuw leest, maar een ander resultaat krijgt - omdat de rij tussendoor is bijgewerkt door een andere transactie. Het lezen is niet-herhaalbaar geworden , zoals in dit voorbeeld:
Om dit probleem op te lossen, stelt u het isolatieniveau van de transactie in op "repeatableread". PostgreSQL zorgt er dan voor dat de tweede (of enige) lezing hetzelfde resultaat oplevert als de eerste lezing. Hier is hetzelfde scenario op het verbeterde isolatieniveau:
Merk op dat het isolatieniveau is gespecificeerd samen met de BEGINstatement. Het is ook mogelijk om dit op verbindingsniveau te specificeren (als verbindingsparameter), als configuratieparameter (default_transaction_isolation
)en met behulp van de instructie SET TRANSACTION.
Serializable
Het volgende isolatieniveau verhelpt het probleem van verloren updates . Updates die in één transactie worden uitgevoerd, kunnen "verloren" gaan of worden overschreven door een andere transactie die toevallig tegelijkertijd wordt uitgevoerd, zoals hier wordt weergegeven:
Hier blokkeert de UPDATE van de tweede transactie, omdat PostgreSQL een slot plaatst om een nieuwe update te voorkomen totdat de eerste transactie is voltooid. De wijziging van de eerste transactie gaat echter verloren, omdat de tweede de rij "overschreef".
Als dit soort gedrag niet acceptabel is, kunt u het isolatieniveau upgraden naar serialiseerbaar:
Op dit niveau mislukt de commit van de tweede transactie. De acties van de tweede transactie waren gebaseerd op feiten die ongeldig waren verklaard tegen de tijd dat deze op het punt stond te plegen.
Hoewel serialisatie het hoogste veiligheidsniveau biedt, betekent dit ook dat de toepassing dergelijke commit-fouten moet detecteren en de hele transactie opnieuw moet proberen.