Documente Academic
Documente Profesional
Documente Cultură
Exemplu: o tranzactie care transferabani dintr-un cont bancar in altul. Este important ca banii sa fie scosi dintr-un cont si pusi in altul
in acelasi moment. Altfel pot aprea probleme ca pierderea banilor sau duplicarea lor in ambele conturi.
Clauza optionala COMMENT permite specificarea unui comentariu asociat tranzactiei. Daca reteaua sau calculatorul cad in timpul
opratiei commit, starea tranzactiei poate fi necunoscuta. In acest caz Oracle memoreaza textul specificat de COMMENT in dictionarul
de date impreuna cu ID tranzactiei.
Exemplu: inserarea informatiei despre un angajat in 3 tabele diferite. Daca se incearca inserarea unui angajat cu id duplicat, exceptia
predefinita DUP_VAL_ON_INDEX este generata. Pentru a ne asigura ca schmibarile la cele 3 tabele sunt anulate, managerul erorii va
executa operatie ROLLBACK.
DECLARE
emp_id NUMBER(6);
emp_lastname VARCHAR2(25);
emp_salary NUMBER(8,2);
emp_jobid VARCHAR2(10);
BEGIN
SELECT employee_id, last_name, salary, job_id INTO emp_id, emp_lastname,emp_salary, emp_jobid
FROM employees WHERE employee_id = 120;
INSERT INTO emp_name VALUES (emp_id, emp_lastname);
INSERT INTO emp_sal VALUES (emp_id, emp_salary);
INSERT INTO emp_job VALUES (emp_id, emp_jobid);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
1
ROLLBACK;
DBMS_OUTPUT.PUT_LINE('Inserts have been rolled back');
END;
Exemplu: marcarea unui punct de salvare inainte de o operatie de insetare. Daca se insereaza o inregistrare duplicat apere eroarea
predefinita DUP_VAL_ON_INDEX. In acest caz se vor anula efectele pana la punctul de salvare, adica efectele operatiei de inserare
numai.
DECLARE
emp_id employees.employee_id%TYPE;
emp_lastname employees.last_name%TYPE;
emp_salary employees.salary%TYPE;
BEGIN
SELECT employee_id, last_name, salary INTO emp_id, emp_lastname,
emp_salary FROM employees WHERE employee_id = 120;
UPDATE emp_name SET salary = salary * 1.1 WHERE employee_id = emp_id;
DELETE FROM emp_name WHERE employee_id = 130;
SAVEPOINT do_insert;
INSERT INTO emp_name VALUES (emp_id, emp_lastname, emp_salary);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
ROLLBACK TO do_insert;
DBMS_OUTPUT.PUT_LINE('Insert has been rolled back');
END;
Cand se anuleaza efectele pana la un punct de salvare, toate punctele de salvare dupa acesta sunt sterse. Punctul de slvare pana la
care s-au anulat efectele nu este sters. Un simplu rollback sau commit sterg toate punctele de salvare.
Punctele de salvare sunt identificatori nedeclarati. Refolosirea lor intr-o tranzactie muta punctul de salvare de la vechea pozitie la
pozitia curenta din tranzactie. Aceasta inseamna ca operatia rollback la punctul de salvare afecteaza numai partea pana curenta din
tranzactie.
DECLARE
emp_id employees.employee_id%TYPE;
emp_lastname employees.last_name%TYPE;
emp_salary employees.salary%TYPE;
BEGIN
SELECT employee_id, last_name, salary INTO emp_id, emp_lastname,
emp_salary FROM employees WHERE employee_id = 120;
SAVEPOINT my_savepoint;
UPDATE emp_name SET salary = salary * 1.1 WHERE employee_id = emp_id;
DELETE FROM emp_name WHERE employee_id = 130;
SAVEPOINT my_savepoint; -- move my_savepoint to current poin
INSERT INTO emp_name VALUES (emp_id, emp_lastname, emp_salary);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
ROLLBACK TO my_savepoint;
DBMS_OUTPUT.PUT_LINE('Transaction rolled back.');
END;
2
4. Setarea proprietatilor tranzactiilor cu comanda SET TRANSACTION
4.1. SET TRANSACTION READ ONLY
SET TRANSACTION se foloseste pentru a incepe o tranzactie read-only sau read-write, pentru a stabili un nivel de izolare sau pentru
a atribui tranzactia curenta unui anumit segment de rollback. Tranzactiile “read-only “ sunt folosite pentru a executa mai multe
interogari “select” in timp ce alti utilizatori modifica acelasi tabele.
Exemplu : managerul unui magazin foloseste o tranzactie read-only pentru a afisa totatulul tranzactiilor pe zi si pe luna trecuta.
Totalurile sunt neafectate de alte modificari pe baza de date in timpul tranzactiei.
DECLARE
daily_order_total NUMBER(12,2);
weekly_order_total NUMBER(12,2);
monthly_order_total NUMBER(12,2);
BEGIN
COMMIT; -- ends previous transaction
SET TRANSACTION READ ONLY NAME 'Calculate Order Totals';
SELECT SUM (order_total) INTO daily_order_total FROM orders
WHERE order_date = SYSDATE;
SELECT SUM (order_total) INTO weekly_order_total FROM orders
WHERE order_date = SYSDATE - 7;
SELECT SUM (order_total) INTO monthly_order_total FROM orders
WHERE order_date = SYSDATE - 30;
COMMIT; -- ends read-only transaction
END;
Daca o tranzactie este setata READ ONLY, toate interogarile din tranzactie vor vedea numai schimbarile efectuate inainte de a incepe
tranzactia. Folosirea unei tranzactii READ ONLY nu afecteaza alti utilizatori sau alte tranzactii.
Numai comenzile SELECT INTO, OPEN, FETCH, CLOSE, LOCK TABLE, COMMIT si ROLLBACK sunt permise intr-o tranzactie read-
only.
Acesta este implicit in Oracle. O posibila operatie din tranzactie poate vizualiza numai datele care au fost deja
terminate (comise) inainte ca opratia respectiva sa inceapa (si nu cand tranzactia a inceput)
Folosirea clauzei ISOLATION LEVEL specifica cum sunt administrate tranzactiile care contin modificari ale bazei de date.
Setarea la SERIALIZABLE : specifica ca o tranzactie care contine limbaj de manipulare a datelor(DML) care asteapta
modificarea oricarei resurse care a fost modificata intr-o alta tranzactie neterminata inca la inceputul tranzactiei serializabile,
atunci DML esueaza.
Setarea la READ COMMITTED: specifica ca o tranzactie care contine limbaj de manipulare a datelor(DML) care cere
blocarea unor inregistrari detinute de alta tranzactie, atunci operatiile DML asteapta pana ce blocarile sunt eliberate.
5. Blocari
Implicit, Oracle blocheaza structurile de date - o caracteristica importanta pentru Oracle.
Se pot cere blocari de date pe anumite inregistrari sau pe tabele intregi daca este nevoie sa se rescrie blocarile implicite. Blocarile
explicite permit blocarea accesului la date in timpul unei tranzactii.
3
Folosirea clauzei FOR UPDATE
Cand se declara un cursor care va fi referit in operatii UPDATE sau DELETE trebuie folosita clauza FOR UPDATE pentru a obtine
blocare exclusiva pe inregistrari
DECLARE
CURSOR c1 IS SELECT employee_id, salary FROM employees
WHERE job_id = 'SA_REP' AND commission_pct > .10
FOR UPDATE NOWAIT;
Comanda SELECT ... FOR UPDATE identifica inregistrarile care vor fi modificate sau sterse, apoi blocheaza fiecare rand din setul
rezultat. Aceasta este folositoare cand se doreste o modificare pe valorile existente din inregistrare(row). In acest caz trebuie asigurat
ca nu se efectueaza modificari asupra randului de catre alt utilizator inainte de update.
Cuvantul cheie optional NOWAIT precizeaza ca nu trebuie asteptat daca randurile cerute au fost blocate de alt utilizator. Controlul este
imediat intors in program pentru a efectua alte oparatii pana cand va putea bloca randurile. Daca se omite NOWAIT, Oracle va astepta
pana cand inregistrarile sunt desponibile.
Cand se interogheaza tabele multiple, randurile din tabele sun blocate numai daca caluza FOR UPDATE OF refera o coloana din acea
tabela. De exemplu, urmatoarea interogare blocheaza randurile din tabela employees, dar nu si din tabela departments.
DECLARE
CURSOR c1 IS SELECT last_name, department_name FROM employees, departments
WHERE employees.department_id = departments.department_id
AND job_id = 'SA_MAN'
FOR UPDATE OF salary;
Exemplu: folosirea clauzei CURRENT OF intr-o instructiune UPDATE sau DELETE pentru a referi ultima inregistrare returnata de un
cursor.
DECLARE
my_emp_id NUMBER(6);
my_job_id VARCHAR2(10);
my_sal NUMBER(8,2);
CURSOR c1 IS SELECT employee_id, job_id, salary FROM employees FOR UPDATE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO my_emp_id, my_job_id, my_sal;
IF my_job_id = 'SA_REP' THEN
UPDATE employees SET salary = salary * 1.02 WHERE CURRENT OF c1;
END IF;
EXIT WHEN c1%NOTFOUND;
END LOOP;
END;
Sesiunea I
Sesiunea II
Tranzactia va esua, deoarece in Sessiunea 1 inregistrarea a fost blocata. Tranzactia din sesiunea 2 va fi executata daca inainte
executam COMMIT sau ROLLBACK pentru a elibera blocarea asupra inregistrarii.
4
Sesiunea I
SQL> rollback;
Rollback complete.
SQL>
Sesiunea II