Oracle SQL: Row locking on select statement

het doel van dit bericht is om uit te leggen hoe je een record op een Oracle-Database vergrendelt met behulp van een SELECT-statement.

Inleiding

het doel van dit bericht is uit te leggen hoe een record op een Oracle-Database kan worden vergrendeld met behulp van een SELECT-statement. Dit stelt ons in staat om een record te vergrendelen zonder de noodzaak om het te veranderen.

hoewel dit misschien niet veel voorkomt, is de waarheid dat we het misschien nodig hebben voor meer complexe programma ‘ s (geïmplementeerd, bijvoorbeeld in PL/SQL), waar we enkele complexe validaties moeten doen voordat we besluiten een bepaald register bij te werken, en we moeten het vergrendeld houden tijdens die validaties, zodat geen enkele andere transactie het tegelijkertijd kan wijzigen.

we zullen SQL Developer gebruiken om te interageren met de database en om de query ‘ s voor deze tutorial uit te voeren.

het zelfde record

vergrendelen zoals gewoonlijk, zullen we beginnen met het maken van een eenvoudige dummy tabel, om onze gegevens vast te houden. Controleer de create voorbeeld hieronder.

create table Worker(WorkerID varchar(20),WorkerName varchar(255),WorkerJob varchar(255),CONSTRAINT PK_Worker PRIMARY KEY (WorkerID));

daarna zullen we enkele dummy records invoegen, dus we hebben gegevens om aan te werken. We zullen drie records invoegen en dan de transactie vastleggen. Je kunt de commit knop gebruiken in het SQL Developer menu of de transactie expliciet vastleggen met een SQL statement.

insert into worker values ('1','John', 'nurse');insert into worker values ('2','Grace', 'farmer');insert into worker values ('3','Smith', 'doctor');

nu zullen we een nieuw niet-gedeeld werkblad openen, zodat we de SQL-verklaringen in onafhankelijke transacties kunnen testen. Controleer figuur 1 over hoe het te doen. U kunt meer lezen over SQL Developer unshared werkbladen in dit vorige bericht.

SQL Developer unshared werkblad

figuur 1-Een nieuw unshared werkblad openen.

nu, het eerste wat we gaan doen is het uitvoeren van een reguliere selectie in beide werkbladen. We zullen een selectie doen om het record te krijgen waar de WorkerID gelijk is aan 1. Doe geen commits of rollbacks, voer gewoon dezelfde query uit in beide werkbladen.

select * from worker where WorkerID = 1;

zoals verwacht is er geen probleem met concurrence en we zullen het record in beide transacties ontvangen (met de werknaam gelijk aan “John”).

nu gaan we terug naar het eerste werkblad (hetzelfde waar we de tabel hebben aangemaakt) en voegen we een “for update” – clausule toe aan het einde van het SELECT statement, zoals hieronder aangegeven. Nogmaals, doe geen commit of rollback.

select * from worker where WorkerID = 1 for update;

wanneer we dit doen, vergrendelen we de records van de resultatenreeks, zonder dat we ze hoeven bij te werken . Met andere woorden, we zijn expliciet vergrendelen de records. Als we ze eenmaal op slot hebben, kunnen we ze updaten als we dat willen. De locks op de records worden vrijgegeven wanneer we de volgende commit of rollback doen .

dus, om te testen of de sloten werken, gaan we nu naar het tweede werkblad (het niet gedeelde werkblad dat we geopend hebben). Daar, als we doen een regelmatige select, zonder de “voor update zin”, zullen we het record zonder enig probleem.

select * from worker where WorkerID = 1;

maar dan, als we de select herhalen, nu met de” for update ” zin op het einde, zal het hangen, omdat andere transactie het record met WorkerID gelijk aan 1 vergrendeld heeft, en we proberen het opnieuw te vergrendelen.

select * from worker where WorkerID = 1 for update;

om het te ontgrendelen, ga je terug naar het eerste werkblad en commit of rollback de transactie. Ga nu terug naar het niet-gedeelde werkblad en het SQL-statement zou moeten zijn uitgevoerd, waarbij de gewenste record wordt geretourneerd.

het vergrendelen van verschillende records

een belangrijk ding om in gedachten te houden is dat alleen de records die deel uitmaken van de resultatenreeks worden vergrendeld door de transactie. Dus, verschillende transacties kunnen doen “selecteren voor update” in verschillende records.

om dit te testen, gaat u naar het eerste werkblad en selecteert u record 1 en 3, met de volgende selecteer zin:

select * from worker where WorkerID = 1 or WorkerID = 3 for update;

ga nu naar het niet-gedeelde werkblad en probeer record 2 te vergrendelen.

select * from worker where WorkerID = 2 for update;

het moet werken en een resultaat retourneren, omdat het record met WorkerID gelijk aan 2 niet werd geblokkeerd door de eerste transactie. Als we nu in hetzelfde niet-gedeelde werkblad proberen de record te vergrendelen met werknemer-ID gelijk aan 1 of de record met werknemer-ID gelijk aan 3 (of beide), blijft deze hangen totdat we de transactie vastleggen of terugdraaien vanaf het eerste werkblad.

gerelateerde inhoud

  • Oracle Select for update statment

Write a Comment

Het e-mailadres wordt niet gepubliceerd.