Tranzacție autonomă în Oracle PL / SQL

⚡ Rezumat inteligent

Instrucțiuni de control al tranzacțiilor în Oracle PL/SQL, și anume COMMIT, ROLLBACK și SAVEPOINT, decid dacă modificările DML în așteptare sunt salvate sau eliminate. O tranzacție autonomă rulează ca un subprogram independent care efectuează validarea sau anularea modificărilor separat de tranzacția principală.

  • 💾 ANGAJARE: Face ca toate modificările DML în așteptare să fie permanente, încheie tranzacția, eliberează blocările și șterge fiecare punct de salvare.
  • ↩️ ROLLBACK: Anulează modificările în așteptare, fie întreaga tranzacție, fie revenind la un PUNCT DE SALVARE denumit.
  • 📌 PUNT DE SALVARE: Marchează un punct în cadrul unei tranzacții, astfel încât o operațiune ROLLBACK TO ulterioară să poată anula doar o parte din lucrare.
  • 🔀 Tranzacție autonomă: Directiva PRAGMA AUTONOMOUS_TRANSACTION permite unui subprogram să se valideze sau să anuleze singur procesul.
  • 🧾 Cazuri de utilizare: Tranzacțiile autonome se potrivesc auditului și înregistrării erorilor, care trebuie să persiste chiar dacă lucrarea principală este anulată.
  • 🤖 Asistență AI: Asistenții AI, cum ar fi GitHub Copilot, redactează blocuri COMMIT, ROLLBACK și PRAGMA și semnalează commit-urile lipsă.

Tranzacție autonomă în Oracle PL/SQL cu COMMIT și ROLLBACK

Ce sunt instrucțiunile TCL în PL/SQL?

TCL este prescurtarea de la Transaction Control Statements (Instrucțiuni de control al tranzacțiilor). Aceste instrucțiuni fie salvează tranzacțiile în așteptare, fie le anulează. Ele joacă un rol vital, deoarece, dacă o tranzacție nu este salvată, modificările făcute prin Declarații DML nu vor fi stocate permanent în baza de date. Mai jos sunt diferitele instrucțiuni TCL din PL / SQL.

Declarație Descriere
COMITEAZA Salvează toate tranzacțiile în așteptare.
REALIZARE Elimină toate tranzacțiile în așteptare.
PUNT DE SALVARE Creează un punct în tranzacție până la care se poate face ulterior o revenire la o versiune anterioară.
ROLLBACK LA Elimină toate tranzacțiile în așteptare până la punctul de salvare specificat.

Tranzacția se va finaliza în următoarele scenarii:

  • Când este emisă oricare dintre declarațiile de mai sus (cu excepția SAVEPOINT).
  • Când sunt emise instrucțiuni DDL (DDL sunt instrucțiuni de auto-commit).
  • Când sunt emise instrucțiuni DCL (DCL sunt instrucțiuni de auto-commit).

Utilizarea SAVEPOINT și ROLLBACK TO

Tabelul de mai sus prezintă SAVEPOINT și ROLLBACK TO, iar împreună vă oferă control parțial asupra unei tranzacții. Un SAVEPOINT marchează un punct denumit în cadrul tranzacției curente. O ROLLBACK ulterioară la acel punct de salvare anulează fiecare modificare făcută după aceasta, păstrând în același timpping munca efectuată înainte de aceasta intactă.

Acest lucru este util atunci când o tranzacție lungă efectuează mai multe SQL pași și doar ultimul pas eșuează. În loc să abandonați întreaga tranzacție, puteți reveni la ultimul punct de salvare valid și puteți continua.

Sintaxă:

SAVEPOINT <savepoint_name>;
   -- one or more DML statements
ROLLBACK TO <savepoint_name>;

Puncte cheie de reținut despre punctele de salvare:

  • Un punct de salvare există doar în tranzacția curentă; o comandă COMMIT sau o comandă ROLLBACK completă șterge fiecare punct de salvare.
  • Când reveniți la un punct de salvare, toate punctele de salvare create după acesta sunt șterse, dar punctul de salvare la care reveniți este păstrat.
  • ROLLBACK TO nu încheie tranzacția; modificările făcute înainte de punctul de salvare rămân în așteptare până când executați COMMIT sau ROLLBACK.
  • Dacă reutilizați un nume de punct de salvare, noul punct de salvare mută markerul în poziția ulterioară.

Deoarece ROLLBACK TO lasă tranzacția deschisă, la final tot decideți dacă să validați modificările rămase sau să le eliminați cu o ROLLBACK completă.

Ce este Tranzacția Autonomă

În PL/SQL, toate modificările efectuate asupra datelor sunt denumite tranzacții. O tranzacție este considerată completă atunci când i se aplică o salvare sau o eliminare. Dacă nu se acordă nicio salvare sau eliminare, atunci tranzacția nu este considerată completă, iar modificările efectuate asupra datelor nu vor fi permanente pe server.

În mod implicit, PL/SQL tratează toate modificările din timpul unei sesiuni ca o singură tranzacție, iar salvarea sau eliminarea acelei tranzacții afectează fiecare modificare pendinte din sesiune. O tranzacție autonomă oferă dezvoltatorului posibilitatea de a face modificări într-o tranzacție separată și de a salva sau elimina acea tranzacție fără a afecta tranzacția principală a sesiunii.

  • O tranzacție autonomă poate fi specificată la nivel de subprogram.
  • A face orice subprogram lucrează într-o tranzacție diferită, cuvântul cheie PRAGMA AUTONOMOUS_TRANSACTION ar trebui dat în secțiunea declarativă a blocului respectiv.
  • Instruiește compilatorul să trateze aceasta ca o tranzacție separată, iar salvarea sau eliminarea în interiorul acestui bloc nu se va reflecta în tranzacția principală.
  • Emiterea comenzilor COMMIT sau ROLLBACK este obligatorie înainte de a părăsi această tranzacție autonomă și a reveni la tranzacția principală, deoarece în orice moment poate fi activă o singură tranzacție.
  • Așadar, odată ce o tranzacție autonomă este pornită, aceasta trebuie salvată și finalizată înainte ca controlul să poată reveni la tranzacția principală.

Sintaxă:

DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
.
BEGIN
<execution_part>
[COMMIT|ROLLBACK]
END;
/

În sintaxa de mai sus, blocul a fost transformat într-o tranzacție autonomă.

Exemplu 1: În acest exemplu, vom înțelege cum funcționează o tranzacție autonomă.

Captura de ecran de mai jos prezintă acest exemplu de tranzacție autonomă și rezultatul său în Oracle.

Exemplu de tranzacție autonomă care comite un bloc imbricat în timp ce tranzacția principală revine la funcționare Oracle PL / SQL

DECLARE
   l_salary   NUMBER;
   PROCEDURE nested_block IS
   PRAGMA autonomous_transaction;
    BEGIN
     UPDATE emp
       SET salary = salary + 15000
       WHERE emp_no = 1002;
   COMMIT;
   END;
BEGIN
   SELECT salary INTO l_salary FROM emp WHERE emp_no = 1001;
   dbms_output.put_line('Before Salary of 1001 is'|| l_salary);
   SELECT salary INTO l_salary FROM emp WHERE emp_no = 1002;
   dbms_output.put_line('Before Salary of 1002 is'|| l_salary);    
   UPDATE emp 
   SET salary = salary + 5000 
   WHERE emp_no = 1001;

nested_block;
ROLLBACK;

 SELECT salary INTO  l_salary FROM emp WHERE emp_no = 1001;
 dbms_output.put_line('After Salary of 1001 is'|| l_salary);
 SELECT salary INTO l_salary FROM emp WHERE emp_no = 1002;
 dbms_output.put_line('After Salary of 1002 is '|| l_salary);
end;

producție

Before:Salary of 1001 is 15000 
Before:Salary of 1002 is 10000 
After:Salary of 1001 is 15000 
After:Salary of 1002 is 25000

Code Explicaţie:

  • Code linia 2: Se declară l_salary ca NUMĂR.
  • Code linia 3: Declararea procedurii nested_block.
  • Code linia 4: Transformarea procedurii nested_block într-o AUTONOMOUS_TRANSACTION.
  • Code liniile 7-9: Creșterea salariului pentru angajatul numărul 1002 cu 15000.
  • Code linia 10: Finalizarea tranzacției autonome.
  • Code liniile 13-16: Imprimarea detaliilor salariale ale angajaților 1001 și 1002 înainte de modificări.
  • Code liniile 17-19: Creșterea salariului pentru angajatul numărul 1001 cu 5000.
  • Code linia 20: Apelarea procedurii nested_block.
  • Code linia 21: Înlăturarea tranzacției principale.
  • Code liniile 22-25: Imprimarea detaliilor salariale ale angajaților 1001 și 1002 după modificări.

Creșterea salarială pentru angajatul numărul 1001 nu este reflectată deoarece tranzacția principală a fost eliminată. Creșterea salarială pentru angajatul numărul 1002 este reflectată deoarece blocul respectiv a fost transformat într-o tranzacție separată și salvat la final.

Deci, indiferent de salvarea sau eliminarea la tranzacția principală, modificările din tranzacția autonomă sunt salvate fără a afecta tranzacția principală.

Când se utilizează tranzacții autonome

Tranzacțiile autonome sunt puternice, așa că este util să știi când sunt potrivite. Rezervă-le pentru activități care trebuie să reușească sau să eșueze independent de tranzacția principală, nu pentru logica de afaceri de bază. Cazurile de utilizare comune includ:

  • Înregistrare de audit: Înregistrați cine a modificat datele sensibile, când și valorile vechi și noi, astfel încât jurnalul să supraviețuiască chiar dacă tranzacția principală este anulată.
  • Eroare la înregistrare: Scrieți o înregistrare de eroare în interiorul unui excepție handler și îl COMMIT, astfel încât detaliile de diagnosticare să fie păstrate în timp ce tranzacția eșuată este eliminată.
  • Contoare și statistici: Avansează un contor de utilizare sau un număr de accesări care trebuie să persiste indiferent de rezultatul apelantului.
  • COMMIT în interiorul unui declanșator: Un declanșator nu poate emite direct o comandă COMMIT; o tranzacție autonomă este singura modalitate acceptată de a face acest lucru.

Evitați tranzacțiile autonome pentru actualizări obișnuite care ar trebui să aibă aceeași soartă ca tranzacția principală. Utilizarea excesivă a acestora poate ascunde date în spatele unor commit-uri independente și poate îngreuna depanarea. De regulă, fiecare bloc autonom trebuie să se termine cu un COMMIT sau un ROLLBACK explicit.

Tranzacții autonome vs. tranzacții regulate

Diferența dintre o tranzacție obișnuită (principală) și o tranzacție autonomă se reduce la domeniul de aplicare și independență. Tabelul de mai jos le compară.

Aspect Tranzacție regulată Tranzacție autonomă
domeniu Partajează o tranzacție de sesiune Rulează ca o tranzacție fiu separată
Efect COMMIT / ROLLBACK Afectează toate modificările de sesiune în așteptare Afectează doar blocul autonom
Declarație Comportament implicit PRAGMA AUTONOMOUS_TRANSACTION în secțiunea declarativă
Efectul revenirii la poziția inițială a părintelui Modificările se pierd Modificările autonome confirmate sunt păstrate
Utilizare tipică Logica de afaceri de bază Audit și înregistrare a erorilor

Spre deosebire de un obișnuit bloc imbricat, ale cărui modificări partajează întotdeauna rezultatul tranzacției care îl încadrează, un bloc autonom este independent. Înțelegerea acestei diferențe vă ajută să decideți când un bloc ar trebui să fie independent și când ar trebui să partajeze rezultatul tranzacției principale.

Întrebări frecvente

Oracle generează comanda ORA-06519 și anulează munca autonomă. Fiecare tranzacție autonomă trebuie să se termine cu un COMMIT sau ROLLBACK explicit înainte ca controlul să revină la tranzacția principală, deoarece este permisă o singură tranzacție activă la un moment dat.

Nu direct. Un declanșator normal nu poate emite comenzi COMMIT sau ROLLBACK. Declararea declanșatorului sau a unei proceduri pe care o apelează cu PRAGMA AUTONOMOUS_TRANSACTION îi permite să își valideze propriile modificări independent de instrucțiunea care a declanșat declanșatorul.

Nu. Odată ce părintele este suspendat, tranzacția autonomă rulează independent și nu poate vedea modificările nevalidate ale părintelui. Aceasta vede doar datele deja validate în baza de date, așadar așteptarea unei blocări a părintelui poate provoca un impas.

Da. Fiecare instrucțiune DDL, cum ar fi CREATE, ALTER sau DROP, emite un COMMIT implicit înainte și după rulare. Orice DML în așteptare din sesiune este validat automat, deci o instrucțiune DDL nu poate fi anulată ulterior.

Un bloc autonom poate apela un altul, iar fiecare își gestionează propriul COMMIT sau ROLLBACK. Oracle limitează numărul de tranzacții active simultan prin parametrul de inițializare TRANSACTIONS, astfel încât imbricarea foarte profundă a blocurilor autonome poate eșua.

Nu. O comandă COMMIT face modificările permanente, eliberează blocările și șterge punctele de salvare, deci nu poate fi anulată cu ROLLBACK. Pentru a inversa datele comise, trebuie să rulați un nou DML. Folosiți SAVEPOINT și ROLLBACK TO pentru anulare parțială înainte de commitere.

Da. Copilotul GitHub elimină logica COMMIT și ROLLBACK, blocurile SAVEPOINT și procedurile PRAGMA AUTONOMOUS_TRANSACTION dintr-un comentariu. RevVedeți plasarea commit-urilor și gestionarea erorilor, deoarece o commit plasată greșit poate corupe limitele tranzacțiilor.

Asistenții inteligenți artificiali scanează procedurile pentru a identifica instrucțiuni COMMIT și ROLLBACK lipsă sau plasate greșit, commit-uri în interiorul buclelor și blocuri autonome neînchise. Această analiză a învățării automate semnalează erorile tranzacțiilor și sugerează limite mai sigure înainte ca codul să ajungă în producție.

Rezumați această postare cu: