Oracle SQL: Row locking on select statement

syftet med detta inlägg är att förklara hur man låser en post i en Oracle-databas med hjälp av ett select-uttalande.

introduktion

syftet med detta inlägg är att förklara hur man låser en post i en Oracle-databas med hjälp av ett select-uttalande. Detta gör att vi kan låsa en post utan att behöva ändra den.

även om detta kanske inte verkar vara ett mycket vanligt användningsfall, är sanningen att vi kan behöva det för mer komplexa program (implementerade till exempel i PL/SQL), där vi behöver göra några komplexa valideringar innan vi bestämmer oss för att uppdatera ett visst register, och vi måste behålla det låst under dessa valideringar, så ingen annan transaktion kan samtidigt ändra den.

vi kommer att använda SQL Developer för att interagera med databasen och för att utföra frågorna för denna handledning.

låsa samma post

som vanligt börjar vi med att skapa ett enkelt dummybord för att hålla våra data. Kontrollera skapa exempel nedan.

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

efter det kommer vi att infoga några dummy-poster, så vi har data att arbeta med. Vi kommer att infoga tre poster och sedan begå transaktionen. Du kan använda commit-knappen på SQL Developer-menyn eller uttryckligen begå transaktionen med en SQL-sats.

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

nu öppnar vi ett nytt odelat kalkylblad för att vi ska kunna testa SQL-satserna i oberoende transaktioner. Kontrollera figur 1 om hur man gör det. Du kan läsa mer om SQL Developer odelade kalkylblad i detta tidigare inlägg.

SQL Developer odelat kalkylblad

Figur 1-öppnar ett nytt odelat kalkylblad.

nu är det första vi ska göra att utföra en vanlig select i båda kalkylbladen. Vi kommer att göra en utvald för att få posten där WorkerID är lika med 1. Gör inga åtaganden eller rollbacks, kör bara samma fråga i båda kalkylbladen.

select * from worker where WorkerID = 1;

som förväntat finns det inga problem med samstämmighet och vi kommer att få posten i båda transaktionerna (med arbetsnamnet lika med ”John”).

nu går vi tillbaka till det första kalkylbladet (samma där vi skapade tabellen) och lägger till en ”för uppdatering” – klausul i slutet av select-uttalandet, som anges nedan. Återigen, gör inte något åtagande eller återgång.

select * from worker where WorkerID = 1 for update;

när vi gör detta låser vi posterna för resultatuppsättningen utan att behöva uppdatera dem . Med andra ord låser vi uttryckligen posterna. Naturligtvis att när vi har dem låsta kan vi uppdatera dem om vi vill. Låsen på skivorna släpps när vi gör nästa commit eller rollback .

så, för att testa om låsen fungerar, går vi nu till det andra kalkylbladet (det odelade kalkylbladet vi öppnade). Där, om vi gör en vanlig val, utan ”för uppdateringsmening”, kommer vi att få posten utan problem.

select * from worker where WorkerID = 1;

men då, om vi upprepar select, nu med meningen” för uppdatering ” i slutet, kommer den att hänga, eftersom annan transaktion har posten med WorkerID lika med 1 låst, och vi försöker låsa den igen.

select * from worker where WorkerID = 1 for update;

för att låsa upp det, gå bara tillbaka till det första kalkylbladet och begå eller återställa transaktionen. Gå nu tillbaka till det odelade kalkylbladet och SQL-satsen borde ha körts och returnerat önskad post.

låsa olika poster

en viktig sak att tänka på är att endast de poster som ingår i resultatuppsättningen är låsta av transaktionen. Så olika transaktioner kan göra” Välj för uppdatering ” i olika poster.

för att testa detta, gå till det första kalkylbladet och välj både post 1 och 3, med följande Välj mening:

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

gå nu till det odelade kalkylbladet och försök låsa Post 2.

select * from worker where WorkerID = 2 for update;

det ska fungera och returnera ett resultat, eftersom posten med WorkerID lika med 2 inte låstes av den första transaktionen. Om vi i samma odelade kalkylblad försöker låsa posten med Worker ID lika med 1 eller posten med Worker ID lika med 3 (eller båda) kommer det att hänga tills vi begår eller återställer transaktionen från det första kalkylbladet.

relaterat innehåll

  • Oracle Välj för uppdateringsförklaring

Write a Comment

Din e-postadress kommer inte publiceras.