Egy PL/SQL program szövegébe közvetlenül csak az SQL DML és tranzakcióvezérlő utasításai építhetők be, a DDL utasítások nem. A DML és tranzakcióvezérlő utasítások bárhol használhatók, ahol végrehajtható utasítások állhatnak. A PL/SQL egy külön eszközt használ arra, hogy minden SQL utasítást alkalmazhassunk egy PL/SQL programban, ez a natív dinamikus SQL, amelyet a 15. fejezetben ismertetünk. Most a statikus SQL lehetőségeit tárgyaljuk. Ezen utasítások szövege a fordításkor ismert, a PL/SQL fordító ugyanúgy kezeli, fordítja őket, mint a procedurális utasításokat.
A PL/SQL-ben a SELECT, DELETE, INSERT, UPDATE, MERGE utasítások speciális változatai használhatók. Mi most a hangsúlyt a speciális jellemzőkre helyezzük, az utasítások részletei megtalálhatók a referenciákban (lásd [8] és [21]).
SELECT INTO
A SELECT INTO utasítás egy vagy több adatbázistáblát kérdez le és a származtatott értékeket változókba vagy egy rekordba helyezi el. Alakja:
SELECT [{ALL|{DISTINCT|UNIQUE}}]
{*|select_kifejezés[[,]select_kifejezés]…}
{INTO {változónév[,változónév]…|rekordnév} | BULK COLLECT INTO kollekciónév[,kollekciónév]…}
FROM {táblahivatkozás| (alkérdés)| TABLE(alkérdés1)} [másodlagos_név] [,{táblahivatkozás| (alkérdés)| TABLE(alkérdés1)} [másodlagos_név]}]… további_utasításrészek;
select_kifejezés:
{NULL|literál|függvényhívás| szekvencianév.{CURRVAL|NEXTVAL}| [sémanév.]{táblanév|nézetnév}.]oszlopnév} [ [AS] másodlagos_név]
táblahivatkozás:
[sémanév.]{táblanév|nézetnév][@ab_kapcsoló]
Az INTO utasításrészben minden select_kifejezéshez meg kell adni egy típuskompatibilis változót, vagy pedig a rekordnak rendelkeznie kell ilyen mezővel. A BULK COLLECT INTO utasításrészt a 12. fejezetben tárgyaljuk.
A FROM utasításrészben az alkérdés egy INTO utasításrészt nem tartalmazó SELECT. A TABLE egy operátor (lásd 12. fejezet), amelynél az alkérdés1 egy olyan SELECT, amely egyetlen oszlopértéket szolgáltat, de az beágyazott tábla vagy dinamikus tömb típusú. Tehát itt egy kollekciót és nem egy skalár értéket kell kezelnünk.
A további_utasításrészek a SELECT utasítás FROM utasításrésze után szabályosan elhelyezhető utasításrészek lehetnek (WHERE, GROUP BY, ORDER BY).
A BULK COLLECT utasításrészt nem tartalmazó SELECT utasításnak pontosan egy sort kell leválogatnia. Ha az eredmény egynél több sorból áll, a TOO_MANY_ROWS kivétel váltódik ki. Ha viszont egyetlen sort sem eredményez, akkor a NO_DATA_FOUND kivétel következik be.
1. példa
DECLARE
v_Ugyfel ugyfel%ROWTYPE;
v_Id ugyfel.id%TYPE;
v_Info VARCHAR2(100);
BEGIN
SELECT *
INTO v_Ugyfel
FROM ugyfel
WHERE id = 15;
SELECT id, SUBSTR(nev, 1, 40) || ' - ' || tel_szam
INTO v_Id, v_Info
FROM ugyfel
WHERE id = 15;
END;
/
2. példa
DECLARE
v_Ugyfel ugyfel%ROWTYPE;
BEGIN
SELECT *
INTO v_Ugyfel
FROM ugyfel
WHERE id = -1;
END;
/
/*
Eredmény:
DECLARE
*
Hiba a(z) 1. sorban:
ORA-01403: nem talált adatot
ORA-06512: a(z) helyen a(z) 4. sornál
*/
DECLARE
v_Ugyfel ugyfel%ROWTYPE;
BEGIN
SELECT *
INTO v_Ugyfel
FROM ugyfel;
END;
/
/*
Eredmény:
DECLARE
*
Hiba a(z) 1. sorban:
ORA-01422: a pontos lehívás (FETCH) a kívántnál több sorral tér vissza
ORA-06512: a(z) helyen a(z) 4. sornál
*/
DELETE
A DELETE utasítás egy adott tábla vagy nézet sorait törli. Alakja:
DELETE [FROM] {táblahivatkozás| (alkérdés)| TABLE(alkérdés1)} [másodlagos_név]
[WHERE {feltétel|CURRENT OF kurzornév}]
[returning_utasításrész];
returning_utasításrész:
RETURNING {egysoros_select_kifejezés[,egysoros_select_kifejezés]…
INTO változó[,változó]…| többsoros_select_kifejezés[,többsoros_select_kifejezés]…
[BULK COLLECT INTO kollekciónév[,kollekciónév]…
A FROM utasításrész elemei megegyeznek a SELECT utasítás FROM utasításrészének elemeivel. A táblából vagy nézetből csak azok a sorok törlődnek, amelyekre igaz a feltétel. A CURRENT OF utasításrész esetén a megadott kurzorhoz rendelt lekérdezésnek rendelkeznie kell a FOR UPDATE utasításrésszel és ekkor a legutolsó FETCH által betöltött sor törlődik.
A returning_utasításrész segítségével a törölt sorok alapján számított értékek kaphatók vissza. Ekkor nem kell ezeket az értékeket a törlés előtt egy SELECT segítségével származtatni. Az értékek változókban, rekordban vagy kollekciókban tárolhatók. A BULK COLLECT utasításrészt a 12. fejezet tárgyalja.
Példa
DECLARE
v_Datum kolcsonzes.datum%TYPE;
v_Hosszabbitva kolcsonzes.hosszabbitva%TYPE;
BEGIN
DELETE FROM kolcsonzes
WHERE kolcsonzo = 15 AND konyv = 20
RETURNING datum, hosszabbitva
INTO v_Datum, v_Hosszabbitva;
END;
/
INSERT
Az INSERT utasítás új sorokkal bővít egy megadott táblát vagy nézetet. Alakja:
INSERT INTO {táblahivatkozás| (alkérdés)| TABLE(alkérdés1)} [másodlagos_név]
[(oszlop[,oszlop]…)]
{{VALUES(sql_kifejezés[,sql_kifejezés]…)| rekord}
[returning_utasításrész]| alkérdés2};
A returning_utasításrész magyarázatát lásd a DELETE utasításnál.
Az oszlop egy adatbázisbeli tábla vagy nézet oszlopneve. Az oszlopok sorrendje tetszőleges, nem kell hogy a CREATE TABLE vagy CREATE VIEW által definiált sorrendet kövesse, viszont minden oszlopnév csak egyszer fordulhat elő. Ha a tábla vagy nézet nem minden oszlopa szerepel, akkor a hiányzók NULL értéket kapnak, vagy a megfelelő CREATE utasításban megadott alapértelmezett értéket veszik fel.
A VALUES utasításrész a megadott oszlopokhoz rendel értékeket SQL kifejezések segítségével. Ha az oszloplista hiányzik, akkor a CREATE utasításban megadott oszlopsorrendben történik az értékhozzárendelés. A kifejezések típusának kompatibilisnek kell lenni a megfelelő oszlopok típusával. Minden oszlophoz pontosan egy értéket kell rendelni, ha az oszloplista szerepel. Teljes sornak tudunk értéket adni egy típuskompatibilis rekord segítségével.
Az alkérdés2 egy olyan SELECT, amelynek eredményeképpen az oszlopok értéket kapnak. Annyi értéket kell szolgáltatnia, ahány oszlop meg van adva, vagy pedig az oszloplista hiányában annyit, ahány oszlopa van a táblának vagy nézetnek. A tábla vagy nézet annyi sorral bővül, ahány sort a lekérdezés visszaad.
Példa
DECLARE
v_Kolcsonzes kolcsonzes%ROWTYPE;
BEGIN
INSERT INTO kolcsonzes (kolcsonzo, konyv, datum)
VALUES (15, 20, SYSDATE)
RETURNING kolcsonzo, konyv, datum, hosszabbitva, megjegyzes
INTO v_Kolcsonzes;
-- rekord használata
v_Kolcsonzes.kolcsonzo := 20;
v_Kolcsonzes.konyv := 25;
v_Kolcsonzes.datum := SYSDATE;
v_Kolcsonzes.hosszabbitva := 0;
INSERT INTO kolcsonzes VALUES v_Kolcsonzes;
END;
/
UPDATE
Az UPDATE utasítás megváltoztatja egy megadott tábla vagy nézet megadott oszlopainak értékét. Alakja:
UPDATE {táblahivatkozás| (alkérdés)| TABLE(alkérdés1)} [másodlagos_név]
SET {{oszlop={sql_kifejezés|(alkérdés2)}| (oszlop[,oszlop]…)=(alkérdés3)}
[,{oszlop={sql_kifejezés|(alkérdés2)}| (oszlop[,oszlop]…)=(alkérdés3)}]…
| ROW=rekord}
[WHERE {feltétel|CURRENT OF kurzornév}]
[returning_utasításrész];
A SET oszlop=sql_kifejezés az oszlopok új értékét egyenként adja meg SQL kifejezések segítségével. A SET oszlop=(alkérdés2) esetén az alkérdés2 egy olyan SELECT, amely pontosan egyetlen sort és egyetlen oszlopot ad vissza, ez határozza meg az oszlop új értékét. Ha oszloplistát adunk meg, akkor az alkérdés3 egy olyan SELECT, amely pontosan egy sort és annyi oszlopot eredményez, ahány elemű az oszloplista. A lekérdezés eredménye az oszloplista sorrendjében írja fölül az oszlopok értékét. A ROW megadása esetén a sornak egy típuskompatibilis rekord segítségével tudunk új értéket adni.
A többi utasításrész leírását lásd a DELETE utasításnál.
Példa
DECLARE
TYPE t_id_lista IS TABLE OF NUMBER;
v_Kolcsonzes kolcsonzes%ROWTYPE;
BEGIN
UPDATE TABLE(SELECT konyvek
FROM ugyfel
WHERE id = 20)
SET datum = datum + 1
RETURNING konyv_id BULK COLLECT INTO v_Id_lista;
SELECT *
INTO v_Kolcsonzes
FROM kolcsonzes
WHERE kolcsonzo = 25 AND konyv = 35;
v_Kolcsonzes.datum := v_Kolcsonzes.datum+1;
v_Kolcsonzes.hosszabbitva := v_Kolcsonzes.hosszabbitva+1;
-- rekord használata
UPDATE kolcsonzes
SET ROW = v_Kolcsonzes
WHERE kolcsonzo = v_Kolcsonzes.kolcsonzo AND konyv = v_Kolcsonzes.konyv;
END;
/
MERGE
A MERGE utasítás a többszörös INSERT és DELETE utasítások elkerülésére való. Alakja:
MERGE INTO tábla [másodlagos_név]
USING {tábla|nézet|alkérdés} [másodlagos_név] ON (feltétel)
WHEN MATCHED THEN UPDATE SET oszlop={kifejezés|DEFAULT}
[,oszlop={kifejezés|DEFAULT}]...
WHEN NOT MATCHED THEN INSERT(oszlop[,oszlop]...)
VALUES ({DEFAULT|kifejezés[,kifejezés]...}];
Az INTO határozza meg a céltáblát, amelyet bővíteni vagy módosítani akarunk.
A USING adja meg az adatok forrását, amely tábla, nézet vagy egy alkérdés lehet.
Az ON utasításrészben megadott feltétel szolgál a beszúrás és módosítás vezérlésére. Minden olyan céltáblasor, amelyre igaz a feltétel, a forrásadatoknak megfelelően módosul. Ha valamelyik sorra a feltétel nem teljesül, az Oracle beszúrást végez a forrásadatok alapján.
A WHEN MATCHED utasításrész a céltábla új oszlopértékét határozza meg. Ez a rész akkor hajtódik végre, ha a feltétel igaz. A WHEN NOT MATCHED utasításrész megadja a beszúrandó sor oszlopértékét, ha a feltétel hamis.
Példa
/*
Szinkronizáljuk a kolcsonzes táblát a 20-as azonosítójú ügyfél esetén
az ugyfel konyvek oszlopához.
*/
DECLARE
c_Uid CONSTANT NUMBER := 20;
BEGIN
MERGE INTO kolcsonzes k
USING (SELECT u.id, uk.konyv_id, uk.datum
FROM ugyfel u, TABLE(u.konyvek) uk
WHERE id = c_Uid) s
ON (k.kolcsonzo = c_Uid AND k.konyv = s.konyv_id)
WHEN MATCHED THEN UPDATE SET k.datum = s.datum
WHEN NOT MATCHED THEN INSERT (kolcsonzo, konyv, datum)
VALUES (c_Uid, s.konyv_id, s.datum);
END;
/
Az Oracle működése közben munkameneteket kezel. Egy felhasználói munkamenet egy alkalmazás vagy egy Oracle-eszköz elindításával, az Oracle-hez való kapcsolódással indul. A munkamenetek egyidejűleg, egymással párhuzamosan, az erőforrásokat megosztva működnek. Az adatintegritás megőrzéséhez (ahhoz, hogy az adatok változásának sorrendje érvényes legyen) az Oracle megfelelő konkurenciavezérlést alkalmaz.
Az Oracle zárakat használ az adatok konkurens elérésének biztosítására. A zár átmeneti tulajdonosi jogkört biztosít a felhasználó számára olyan adatbázisbeli objektumok fölött, mint például egy teljes tábla vagy egy tábla bizonyos sorai. Más felhasználó nem módosíthatja az adatokat mindaddig, amíg a zárolás fennáll. Az Oracle automatikus zárolási mechanizmussal rendelkezik, de a felhasználó explicit módon is zárolhat.
Ha egy táblát az egyik felhasználó éppen lekérdez, egy másik pedig módosít, akkor a módosítás előtti adatokat visszagörgető szegmensekben tárolja, ezzel biztosítva az olvasási konzisztenciát.
A tranzakció nem más, mint DML-utasítások sorozata, amelyek a munka egyik logikai egységét alkotják. A tranzakció utasításainak hatása együtt jelentkezik. A tranzakció sikeres végrehajtása esetén a módosított adatok véglegesítődnek, a tranzakcióhoz tartozó visszagörgetési szegmensek újra felhasznáhatóvá válnak. Ha viszont valamilyen hiba folytán a tranzakció sikertelen (bármelyik utasítása nem hajtható végre), akkor visszagörgetődik, és az adatbázis tranzakció előtti állapota nem változik meg. Az Oracle lehetőséget biztosít egy tranzakció részleges visszagörgetésére is.
Minden SQL utasítás egy tranzakció része. A tranzakciót az első SQL utasítás indítja el. Ha egy tranzakció befejeződött, a következő SQL utasítás új tranzakciót indít el.
A tranzakció explicit véglegesítésére a COMMIT utasítás szolgál, amelynek alakja:
COMMIT [WORK];
A WORK alapszó csak az olvashatóságot szolgálja, nincs szemantikai jelentése.
A COMMIT a tranzakció által okozott módosításokat átvezeti az adatbázisba és láthatóvá teszi azokat más munkamenetek számára, felold minden – a tranzakció működése közben elhelyezett – zárat és törli a mentési pontokat.
A SAVEPOINT utasítással egy tranzakcióban mentési pontokat helyezhetünk el. Ezek a tranzakció részleges visszagörgetését szolgálják. Az utasítás alakja:
SAVEPOINT név;
A név nemdeklarált azonosító, amely a tranzakció adott pontját jelöli meg. A név egy másik SAVEPOINT utasításban felhasználható. Ekkor a később kiadott utasítás hatása lesz érvényes.
A visszagörgetést a ROLLBACK utasítás végzi, alakja:
ROLLBACK [WORK] [TO [SAVEPOINT] mentési_pont];
A WORK és a SAVEPOINT nem bír szemantikai jelentéssel.
Az egyszerű ROLLBACK utasítás érvényteleníti a teljes tranzakció hatását (az adatbázis változatlan marad), oldja a zárakat és törli a mentési pontokat. A tranzakció befejeződik.
A TO utasításrésszel rendelkező ROLLBACK a megadott mentési pontig görgeti vissza a tranzakciót, a megadott mentési pont érvényben marad, az azt követők törlődnek, a mentési pont után elhelyezett zárak feloldásra kerülnek és a tranzakció a megadott mentési ponttól folytatódik.
Az Oracle minden INSERT, UPDATE, DELETE utasítás elé elhelyez egy implicit (a felhasználó számára nem elérhető) mentési pontot. Ha az adott utasítás sikertelen, akkor azt az Oracle automatikusan visszagörgeti. Ha azonban az utasítás egy nem kezelt kivételt vált ki, akkor a gazdakörnyezet dönt a visszagörgetésről.
Azt javasoljuk, hogy minden PL/SQL programban explicit módon véglegesítsük vagy görgessük vissza a tranzakciókat. Ha ezt nem tesszük meg, a program lefutása után a tranzakció befejeződése attól függ, hogy milyen tevékenység következik. Egy DDL, DCL vagy COMMIT utasítás kiadása, vagy az EXIT, DISCONNECT, QUIT parancs végrehajtása véglegesíti a tranzakciót, a ROLLBACK utasítás vagy az SQL*Plus munkamenet abortálása pedig visszagörgeti azt.
Nagyon fontos megjegyezni, hogy egy PL/SQL blokk és a tranzakció nem azonos fogalmak. A blokk kezdete nem indít tranzakciót, mint ahogy a záró END sem jelenti a tranzakció befejeződését. Egy blokkban akárhány tranzakció elhelyezhető és egy tranzakció akárhány blokkon átívelhet.
A tranzakció tulajdonságai
Egy tranzakció tulajdonságait a SET TRANSACTION utasítással állíthatjuk be. Ennek az utasításnak
mindig a tranzakció első utasításának kell lenni. Alakja:
SET TRANSACTION{READ ONLY|
READ WRITE|
ISOLATION LEVEL {SERIALIZABLE|
READ COMMITTED}|
USE ROLLBACK SEGMENT visszagörgető_szegmens}
[NAME sztring];
A READ ONLY egy csak olvasható tranzakciót indít el. A csak olvasható tranzakció lekérdezései az adatbázisnak azt a pillanatfelvételét látják, amely a tranzakció előtt keletkezik. Más felhasználók és tranzakciók által okozott változtatásokat a tranzakció nem látja. Egy csak olvasható tranzakcióban SELECT INTO (FOR UPDATE nélkül), OPEN, FETCH, CLOSE, LOCK TABLE, COMMIT és ROLLBACK utasítások helyezhetők el. A csak olvasható tranzakció nem generál visszagörgetési információt.
A READ WRITE az aktuális tranzakciót olvasható-írható tranzakcióvá nyilvánítja. A tranzakcióban minden DML-utasítás használható, ezek ugyanazon visszagörgető szegmensen dolgoznak.
Az ISOLATION LEVEL az adatbázist módosító tranzakciók kezelését adja meg. A READ COMMITTED az alapértelmezett izolációs szint, ennél szigorúbb izolációs szintet a SERIALIZABLE explicit megadásával írhatunk elő. Az izolációs szintekről bővebben lásd [15].
A USE ROLLBACK SEGMENT az aktuális tranzakcióhoz a megadott visszagörgető szegmenst rendeli és azt olvasható-írható tranzakcióvá teszi.
A NAME által a tranzakcióhoz hozzárendelt sztring hozzáférhető a tranzakció futása alatt, lehetővé téve hosszú tranzakciók monitorozását vagy elosztott tranzakcióknál a vitás tranzakciók kezelését.
Explicit zárolás
Az Oracle automatikusan zárolja az adatokat a feldolgozásnál. A felhasználó azonban explicit módon is zárolhat egy teljes táblát vagy egy tábla bizonyos sorait.
A SELECT FOR UPDATE utasítással a kérdés által leválogatott sorok egy későbbi UPDATE vagy DELETE utasítás számára a lekérdezés végrehajtása után lefoglalásra kerülnek. Ezt akkor tegyük meg, ha biztosak akarunk lenni abban, hogy az adott sorokat más felhasználó nem módosítja addig, míg mi a módosítást végre nem hajtjuk.
Ha egy olyan UPDATE vagy DELETE utasítást használunk, amelyikben van CURRENT OF utasításrész, akkor a kurzor lekérdezésében (lásd 8. fejezet) kötelező a FOR UPDATE utasításrész szerepeltetése. Az utasításrész alakja:
FOR UPDATE [NOWAIT]
A NOWAIT hiánya esetén az Oracle vár addig, amíg a sorok elérhetők lesznek, ha viszont megadjuk, akkor a sorok más felhasználó által történt zárolása esetén egy kivétel kiváltása mellett a vezérlés azonnal visszatér a programhoz, hogy az más tevékenységet hajthasson végre, mielőtt újra próbálkozna a zárolással.
A LOCK TABLE utasítás segítségével egy vagy több teljes táblát tudunk zárolni a megadott módon. Alakja:
LOCK TABLE tábla[,tábla]… IN mód MODE [NOWAIT];
A mód a következők valamelyike lehet: ROW SHARE, ROW EXCLUSIVE, SHARE, SHARE UPDATE, SHARE ROW EXCLUSIVE, EXCLUSIVE.
A NOWAIT jelentése az előbbi.
Az Oracle zárolási módjairól bővebben lásd [15] és [21].
Autonóm tranzakciók
Egy tranzakció működése közben elindíthat egy másik tranzakciót is. Gyakran előfordul,
hogy a másodikként indult tranzakció az indító tranzakció hatáskörén kívül működik. Az ilyen szituációk kezelésére vezeti be az Oracle az autonóm tranzakció fogalmát. Az autonóm tranzakció egy másik tranzakció (a fő tranzakció) által elindított, de tőle független tranzakció. Az autonóm tranzakció teljesen független, nincs megosztott zár, erőforrás vagy egyéb függőség a fő tranzakcióval. Segítségével moduláris, az újrafelhasználást jobban segítő szoftverkomponensek állíthatók elő.
Az autonóm tranzakció létrehozására egy pragma szolgál, melynek alakja:
PRAGMA AUTONOMOUS_TRANSACTION;
Ez a pragma egy rutin deklarációs részében helyezhető el és a rutint autonóm tranzakciónak deklarálja. A rutin itt a következők valamelyikét jelenti:
külső szinten álló név nélküli blokk (lásd 6.1. alfejezet);
lokális, tárolt vagy csomagbeli alprogram (lásd 6.2. alfejezet és 9., 10. fejezet);
objektumtípus metódusa (lásd 14. fejezet).
Javasoljuk, hogy az olvashatóság kedvéért a pragma a deklarációs rész elején legyen elhelyezve.
Egy csomag összes alprogramját nem tudjuk egyszerre autonómmá tenni (a pragma nem állhat csomagszinten).
Beágyazott blokk nem lehet autonóm. Trigger törzse viszont deklarálható autonómnak, illetve lehet autonómnak deklarált eljárás hívása.
Az Oracle nem támogatja a beágyazott tranzakciókat. Az autonóm tranzakció fogalma nem ekvivalens a beágyazott tranzakció fogalmával, ugyanis a beágyazott tranzakciók teljes mértékben a fő tranzakció részei, tőle függnek minden értelemben.
Az autonóm és beágyazott tranzakciók közötti különbségek a következők:
Az autonóm tranzakció és a fő tranzakció erőforrásai különböznek, a beágyazott és fő tranzakcióé közösek.
Az autonóm tranzakció visszagörgetése független a fő tranzakció visszagörgetésétől. A beágyazott tranzakció viszont visszagörgetésre kerül, ha a fő tranzakció visszagörgetésre került.
Az autonóm tranzakció véglegesítése után az általa okozott változások azonnal láthatók minden más tranzakció számára. A beágyazott tranzakció véglegesítése utáni változások csak a fő tranzakcióban láthatók, más tranzakciók azokat csak a fő tranzakció véglegesítése után látják.
Egy autonómnak deklarált rutin egymás után több autonóm tranzakciót is végrehajthat, azaz a kiadott COMMIT vagy ROLLBACK nem jelenti a rutin befejezését.
Példa
CREATE TABLE a_tabla (oszlop NUMBER);
DECLARE
PROCEDURE autonom(p NUMBER) IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
/* Első autonóm tranzakció kezdete - A1 */
INSERT INTO a_tabla VALUES(p);
/* Második autonóm tranzakció kezdete - A2*/
INSERT INTO a_tabla VALUES(p+1);
COMMIT;
END;
BEGIN
/* Itt még a fő tranzakció fut - F */
SAVEPOINT kezdet;
/* Az eljáráshívás autonóm tranzakciót indít */
autonom(10);
/* A fő tranzakcó visszagörgetése */
ROLLBACK TO kezdet;
END;
/
SELECT * FROM a_tabla;
/*
OSZLOP
-----------
10
11
*/
Meg kell jegyezni, hogy mind az A1, mind az A2 tranzakció számára F a fő tranzakció.
Mielőtt a vezérlés kilép az autonóm rutinból, az utolsó tranzakciót is be kell fejezni, annak változtatásait vagy véglegesíteni kell, vagy vissza kell görgetni. Ellenkező esetben a be nem fejezett autonóm tranzakciót az Oracle implicit módon visszagörgeti és a fő tranzakcióban a futását indító helyen (ez lehet egy alprogramhívás, lehet a futtató környezet névtelen blokk esetén, de lehet egy egyszerű DML utasítás hívása is, amelynek hatására egy trigger fut le, elindítva egy autonóm tranzakciót) kivételt vált ki.
Egy autonóm tranzakcióból új, tőle független autonóm tranzakció indítható, amely az indító tranzakciótól és az azt indító fő tranzakciótól is független. Vagyis ha FT fő tranzakcióból indul egy AT1 autonóm tranzakció, akkor AT1-ből is indulhat egy AT2 autonóm tranzakció, amely számára AT1 lesz a fő tranzakció. Ekkor mindhárom tranzakció egymástól független lesz. Az adatbázisban az összes munkamenetben együttvéve egy időben megengedett befejezetlen tranzakciók maximális számát az Oracle TRANSACTIONS inicializációs paramétere határozza meg.
Felhasználó által definiált zárak
A DBMS_LOCK csomag lehetőséget ad felhasználói zárak létrehozására. Lefoglalhatunk egy új zárat megadott zárolási móddal, elnevezhetjük azt, hogy más munkamenetekben és más adatbázis-példányokban is látható legyen, megváltoztathatjuk a zárolás módját, és végül feloldhatjuk. A DBMS_LOCK az Oracle Lock Managementet használja, ezért egy felhasználói zár teljesen megegyezik egy Oracle-zárral, így képes például holtpont detektálására.
A felhasználói zárak segítségével