2.1 Citiți neangajat
„Nivelul de izolare a tranzacțiilor” se referă la gradul de protecție oferit de mecanismele interne ale SGBD (adică, care nu necesită programare specială) față de toate sau unele dintre tipurile de inconsecvențe de date de mai sus care apar în timpul executării paralele a tranzacțiilor. Standardul SQL-92 definește o scară de patru niveluri de izolare:
- Citiți neangajat
- Citiți angajat
- Lectură repetabilă
- Serializabil
Primul dintre ele este cel mai slab, ultimul este cel mai puternic, fiecare dintre ele ulterioare le include pe toate precedentele.
Cel mai scăzut (primul) nivel de izolare. Dacă mai multe tranzacții paralele încearcă să modifice același rând de tabel, atunci rândul final va avea o valoare determinată de întregul set de tranzacții finalizate cu succes. În acest caz, este posibil să citiți nu numai date inconsistente din punct de vedere logic, ci și date ale căror modificări nu au fost încă înregistrate.
O modalitate tipică de implementare a acestui nivel de izolare este de a bloca datele în timp ce comanda de modificare este în curs de execuție, ceea ce asigură că comenzile de modificare pe aceleași rânduri rulate în paralel sunt de fapt executate secvențial și că niciuna dintre modificări nu este pierdută. Tranzacțiile numai în citire nu se blochează niciodată sub acest nivel de izolare.
2.2 Citire angajată
Majoritatea SGBD-urilor industriale, în special Microsoft SQL Server, PostgreSQL și Oracle, utilizează acest nivel în mod implicit. La acest nivel, este asigurată protecție împotriva drafturilor, citirii „murdare”, totuși, în timpul operațiunii unei tranzacții, alta poate fi finalizată cu succes, iar modificările efectuate de aceasta sunt fixate. Ca rezultat, prima tranzacție va funcționa cu un set de date diferit.
Implementarea unei citiri complete se poate baza pe una dintre două abordări: blocare sau versiune.
Blocarea datelor care pot fi citite și modificabile.
Constă în faptul că tranzacția de scriere blochează datele mutabile pentru citirea tranzacțiilor care operează la nivelul read committed sau mai mare până la finalizare, prevenind astfel citirea „murdară”, iar datele blocate de tranzacția de citire sunt eliberate imediat după finalizarea operației SELECT
( astfel, o situație de „citire nerepetabilă” poate apărea la un anumit nivel de izolare).
Salvarea mai multor versiuni de rânduri care se modifică în paralel.
De fiecare dată când se schimbă un rând, SGBD creează o nouă versiune a acestui rând, cu care tranzacția care a schimbat datele continuă să funcționeze, în timp ce orice altă tranzacție „de citire” returnează ultima versiune comisă. Avantajul acestei abordări este că este mai rapidă deoarece previne blocarea. Cu toate acestea, necesită, în comparație cu primul, un consum semnificativ mai mare de RAM, care este cheltuit pentru stocarea versiunilor de rând.
În plus, atunci când mai multe tranzacții schimbă datele în paralel, se poate crea o situație în care mai multe tranzacții concurente fac modificări inconsecvente la aceleași date (din moment ce nu există blocări, nimic nu va împiedica acest lucru). Apoi tranzacția care se comite prima își va salva modificările în baza de date principală, iar tranzacțiile paralele rămase vor fi imposibil de comis (deoarece acest lucru va duce la pierderea actualizării primei tranzacții). Singurul lucru pe care SGBD-ul îl poate face într-o astfel de situație este să anuleze restul tranzacțiilor și să emită un mesaj de eroare „Înregistrarea a fost deja schimbată”.
O metodă specifică de implementare este aleasă de dezvoltatorii SGBD, iar în unele cazuri poate fi personalizată. Deci, în mod implicit, MS SQL folosește blocări, dar (în versiunea 2005 și superioară) la setarea parametrului READ_COMMITTED_SNAPSHOT
bazei de date, trece la strategia de versiuni, Oracle funcționează inițial numai conform schemei versiuni. În Informix, puteți preveni conflictele între tranzacțiile de citire și scriere prin setarea unei opțiuni de configurare USELASTCOMMITTED
(începând cu versiunea 11.1) care face ca tranzacția de citire să primească cele mai recente date comise.
2.3 Citire repetabilă
Nivelul la care o tranzacție de citire „nu vede” se modifică în datele pe care le-a citit anterior. În același timp, nicio altă tranzacție nu poate modifica datele citite de tranzacția curentă până la încheierea acesteia.
Blocările în modul partajat sunt aplicate tuturor datelor citite de orice instrucțiune dintr-o tranzacție și sunt menținute până la finalizarea tranzacției. Acest lucru împiedică alte tranzacții să modifice rândurile care au fost citite de tranzacția în așteptare. Cu toate acestea, alte tranzacții pot introduce linii noi care corespund condițiilor de căutare pentru instrucțiunile conținute în tranzacția curentă. Când instrucțiunea este repornită de tranzacția curentă, vor fi preluate noi rânduri, rezultând o citire fantomă.
Având în vedere că blocările partajate sunt păstrate până la sfârșitul tranzacției, în loc să fie eliberate la sfârșitul fiecărei declarații, gradul de concurență este mai mic decât nivelul de izolare READ COMMITTED
. Prin urmare, în general, nu este recomandat să utilizați în mod inutil acest nivel și niveluri superioare de tranzacție.
2.4 Serializabil
Cel mai înalt nivel de izolare; tranzacțiile sunt complet izolate unele de altele, fiecare se execută ca și cum nu ar exista tranzacții paralele. Numai la acest nivel tranzacțiile concurente nu sunt supuse efectului de „citire fantomă”.
2.5 Suport pentru izolarea tranzacțiilor în DBMS real
SGBD-ul tranzacțional nu acceptă întotdeauna toate cele patru niveluri și poate introduce și altele suplimentare. Există, de asemenea, diverse nuanțe în asigurarea izolației.
Deci, în principiu, Oracle nu acceptă nivelul zero, deoarece implementarea tranzacțiilor exclude „citurile murdare” și nu permite în mod oficial setarea nivelului de citire repetabilă, adică acceptă doar (în mod implicit) Read committed
și Serializable
. În același timp, la nivelul comenzilor individuale, garantează de fapt repetabilitatea citirii (dacă o comandă SELECT
din prima tranzacție selectează un set de rânduri din baza de date și, în acest moment, o a doua tranzacție paralelă modifică unele dintre aceste rânduri, atunci setul de rezultate primit de prima tranzacție va conține rânduri neschimbate, ca și cum nu ar exista o a doua tranzacție). Oracle acceptă, de asemenea, așa-numitele READ-ONLY
tranzacții, care corespund cu Serializable
, dar nu pot modifica datele în sine.
Și Microsoft SQL Server acceptă toate cele patru niveluri standard de izolare a tranzacțiilor și, în plus, nivelul SNAPSHOT, la care tranzacția vede starea datelor care a fost comisă înainte de a fi lansată, precum și modificările făcute de ea însăși, adică se comportă ca dacă a primit la pornire, un instantaneu al datelor DB și funcționează cu el. Diferența față de Serialized este că nu sunt utilizate blocaje, dar, ca rezultat, efectuarea modificărilor ar putea să nu fie posibilă dacă o tranzacție concomitentă a schimbat aceleași date înainte; în acest caz, a doua tranzacție, atunci când încearcă să se execute, COMMIT
va genera un mesaj de eroare și va fi anulată.
GO TO FULL VERSION