cílem tohoto příspěvku je vysvětlit, jak zamknout záznam v databázi Oracle pomocí příkazu select.
Úvod
cílem tohoto příspěvku je vysvětlit, jak zamknout záznam v databázi Oracle pomocí příkazu select. To nám umožňuje zamknout záznam bez nutnosti jej měnit.
i když se to nemusí zdát příliš běžným případem použití, pravdou je, že jej můžeme potřebovat pro složitější programy (implementované například v PL/SQL), kde musíme provést některé složité validace, než se rozhodneme aktualizovat určitý registr, a musíme jej udržovat uzamčený během těchto validací, takže žádná jiná transakce jej nemůže současně upravit.
budeme používat SQL Developer pro interakci s databází a provádět dotazy pro tento tutoriál.
zamknutím stejného záznamu
jako obvykle začneme vytvořením jednoduché fiktivní tabulky, která uchová naše data. Zkontrolujte níže vytvořit příklad.
create table Worker(WorkerID varchar(20),WorkerName varchar(255),WorkerJob varchar(255),CONSTRAINT PK_Worker PRIMARY KEY (WorkerID));
poté vložíme nějaké fiktivní záznamy, takže máme data, na kterých musíme pracovat. Vložíme tři záznamy a poté transakci odevzdáme. Můžete použít tlačítko odevzdání v nabídce SQL Developer nebo transakci explicitně odevzdat příkazem SQL.
insert into worker values ('1','John', 'nurse');insert into worker values ('2','Grace', 'farmer');insert into worker values ('3','Smith', 'doctor');
nyní otevřeme nový nesdílený list, abychom mohli testovat příkazy SQL v nezávislých transakcích. Zkontrolujte obrázek 1, Jak to udělat. Můžete si přečíst více o SQL Developer nesdílené listy v tomto předchozím příspěvku.
Obrázek 1-Otevření nového nesdíleného listu.
nyní první věc, kterou uděláme, je provedení pravidelného výběru v obou listech. Uděláme výběr, abychom získali záznam, kde se WorkerID rovná 1. Neprovádějte žádné odevzdání ani vrácení, stačí spustit stejný dotaz v obou listech.
select * from worker where WorkerID = 1;
podle očekávání není problém se souběhem a záznam obdržíme v obou transakcích (s pracovním jménem rovným „Johnovi“).
nyní se vrátíme k prvnímu listu (stejný, kde jsme vytvořili tabulku) a na konec příkazu select přidáme klauzuli „pro aktualizaci“, jak je uvedeno níže. Znovu, nedělejte žádné odevzdání ani vrácení zpět.
select * from worker where WorkerID = 1 for update;
když to uděláme, zamykáme záznamy sady výsledků, aniž bychom je museli aktualizovat . Jinými slovy, výslovně uzamykáme záznamy. Samozřejmě, že jakmile je máme uzamčené, můžeme je aktualizovat, pokud chceme. Zámky na záznamech jsou uvolněny, když provedeme další odevzdání nebo vrácení zpět .
abychom otestovali, zda zámky fungují, nyní přejdeme do druhého listu(nesdílený list, který jsme otevřeli). Tam, pokud uděláme pravidelný výběr, bez věty „pro aktualizaci“, získáme záznam bez problémů.
select * from worker where WorkerID = 1;
ale pak, pokud zopakujeme výběr, nyní s větou „pro aktualizaci“ na konci, bude viset, protože jiná transakce má záznam s WorkerID rovný 1 zamčený a snažíme se jej znovu zamknout.
select * from worker where WorkerID = 1 for update;
Chcete-li jej odemknout, stačí se vrátit do prvního listu a transakci odevzdat nebo vrátit zpět. Nyní se vraťte do nesdíleného listu a příkaz SQL by měl být proveden a vrátit požadovaný záznam.
zamykání různých záznamů
jedna důležitá věc, kterou je třeba mít na paměti, je, že transakcí jsou uzamčeny pouze záznamy, které jsou součástí sady výsledků. Takže různé transakce mohou dělat „vybrat pro aktualizaci“ v různých záznamech.
Chcete-li to otestovat, přejděte do prvního listu a vyberte záznam 1 i 3 s následující větou select:
select * from worker where WorkerID = 1 or WorkerID = 3 for update;
Nyní přejděte do nesdíleného listu a zkuste zamknout záznam 2.
select * from worker where WorkerID = 2 for update;
mělo by fungovat a vrátit výsledek, protože záznam s WorkerID rovný 2 nebyl uzamčen první transakcí. Nyní, pokud se ve stejném nesdíleném listu pokusíme uzamknout záznam pomocí ID pracovníka rovného 1 nebo záznamu S ID pracovníka rovným 3 (nebo oběma), bude viset, dokud neprovedeme nebo nevrátíme transakci z prvního listu.
související obsah
- Oracle Select for update statment