ennek a bejegyzésnek az a célja, hogy elmagyarázza, hogyan lehet egy rekordot lezárni egy Oracle adatbázisban, egy select utasítás segítségével.
Bevezetés
ennek a bejegyzésnek az a célja, hogy elmagyarázza, hogyan lehet egy rekordot lezárni egy Oracle adatbázisban egy select utasítás segítségével. Ez lehetővé teszi számunkra, hogy rögzítsünk egy rekordot anélkül, hogy meg kellene változtatnunk.
bár ez nem tűnik túl gyakori használati esetnek, az igazság az, hogy bonyolultabb programokhoz (például PL/SQL-ben megvalósítva) szükségünk lehet rá, ahol néhány összetett érvényesítést kell elvégeznünk, mielőtt egy bizonyos regiszter frissítése mellett döntünk, és ezen érvényesítések során zárolva kell tartanunk, így egyetlen más tranzakció sem tudja egyidejűleg módosítani.
az SQL Developer programot fogjuk használni az adatbázissal való interakcióhoz és az oktatóanyag lekérdezéseinek végrehajtásához.
ugyanazon rekord lezárása
mint általában, egy egyszerű dummy táblázat létrehozásával kezdjük az adatok tárolásához. Ellenőrizze a példa létrehozása alább.
create table Worker(WorkerID varchar(20),WorkerName varchar(255),WorkerJob varchar(255),CONSTRAINT PK_Worker PRIMARY KEY (WorkerID));
ezt követően beillesztünk néhány dummy rekordot, így van adatunk dolgozni. Három rekordot helyezünk be, majd elkötelezzük a tranzakciót. Használhatja az SQL Developer menü commit gombját, vagy kifejezetten elkötelezheti a tranzakciót egy SQL utasítással.
insert into worker values ('1','John', 'nurse');insert into worker values ('2','Grace', 'farmer');insert into worker values ('3','Smith', 'doctor');
most megnyitunk egy új, meg nem osztott munkalapot, hogy tesztelhessük az SQL utasításokat független tranzakciókban. Ellenőrizze az 1. ábrát, hogyan kell csinálni. Az SQL Developer unshared munkalapjairól ebben az előző bejegyzésben olvashat többet.
1.ábra – új megosztatlan munkalap megnyitása.
most az első dolog, amit meg fogunk tenni, a rendszeres kiválasztás végrehajtása mindkét munkalapon. Mi fog tenni egy select, hogy a rekord, ahol a WorkerID egyenlő 1. Ne végezzen semmilyen kötelezettséget vagy visszagörgetést, csak hajtsa végre ugyanazt a lekérdezést mindkét munkalapon.
select * from worker where WorkerID = 1;
ahogy az várható volt, nincs probléma az egyetértéssel, és mindkét tranzakcióban megkapjuk a rekordot (a WorkerName megegyezik a “John” – val).
most visszatérünk az első munkalapra (ugyanaz, ahol létrehoztuk a táblázatot), és hozzáadunk egy “frissítéshez” záradékot a select utasítás végén, amint azt az alábbiakban jeleztük. Újra, ne végezzen semmilyen kötelezettséget vagy visszagörgetést.
select * from worker where WorkerID = 1 for update;
amikor ezt tesszük, zároljuk az eredményhalmaz rekordjait, anélkül, hogy frissíteni kellene őket . Más szavakkal, kifejezetten zároljuk a rekordokat. Természetesen, ha egyszer már őket zárva, tudjuk frissíteni őket, ha akarjuk. A rekordok zárolása akkor szabadul fel, amikor a következő elkövetést vagy visszagörgetést végezzük .
Tehát annak teszteléséhez, hogy a zárak működnek-e, most a második munkalapra megyünk (a megosztott munkalapra, amelyet megnyitottunk). Ott, ha rendszeresen választunk, a “frissítési mondat” nélkül, minden probléma nélkül megkapjuk a rekordot.
select * from worker where WorkerID = 1;
de akkor, ha megismételjük a select, most a “for update” mondat a végén, akkor lefagy, mivel más tranzakció a rekord WorkerID egyenlő 1 zárva, és megpróbáljuk lezárni újra.
select * from worker where WorkerID = 1 for update;
a feloldáshoz csak menjen vissza az első munkalapra, és végezze el vagy vonja vissza a tranzakciót. Most térjen vissza a meg nem osztott munkalapra, és az SQL utasításnak végre kellett volna hajtania, visszaadva a kívánt rekordot.
különböző rekordok zárolása
fontos szem előtt tartani, hogy csak az eredményhalmaz részét képező rekordokat zárolja a tranzakció. Tehát a különböző tranzakciók különböző rekordokban “kiválaszthatják a frissítést”.
ennek teszteléséhez LÉPJEN az első munkalapra, és válassza ki mind az 1., mind a 3. rekordot, a következő select mondattal:
select * from worker where WorkerID = 1 or WorkerID = 3 for update;
most menjen a meg nem osztott munkalapra, és próbálja meg lezárni a 2.rekordot.
select * from worker where WorkerID = 2 for update;
működnie kell, és eredményt kell adnia, mivel a 2-es WorkerID azonosítóval rendelkező rekordot az első tranzakció nem zárolta. Most, ha ugyanabban a meg nem osztott munkalapban megpróbáljuk lezárni a rekordot az 1-es Munkásazonosítóval vagy a 3-as (vagy mindkettő) Munkásazonosítóval, akkor addig fog lógni, amíg el nem kötelezzük vagy vissza nem állítjuk a tranzakciót az első munkalapról.
kapcsolódó tartalom
- Oracle Select for update statment