Upload
eancrimicri
View
288
Download
0
Embed Size (px)
DESCRIPTION
baze date
Citation preview
Cap. 5. Tranzacții
1
Cap. 5. Tranzacţii
Până în acest moment baza de date a fost privită static fără să intereseze operaţiile de
transfer a datelor. Viziunea statică asupra bazei de date ascunde însă multe probleme a căror
rezolvare este fundamentală pentru o utilizare corectă a bazei de date. Prin prelucrarea datelor,
baza de date trece din starea prezentă S1 într-o stare următoare S2.
Se spune că o bază de date se află într-o stare stabilă dacă şi numai dacă în această stare
sunt rezolvate toate restricţiile de integritate impuse bazei de date.
Se spune că o bază de date se află într-o stare instabilă dacă în această stare cel puţin o
restricţie de integritate nu este satisfăcută.
Prelucrările asupra bazei de date trebuie astfel realizate încât baza de date să ajungă
întotdeauna într-o stare stabilă.
Integritatea BD presupune protecţia datelor împotriva unor distrugeri accidentale
determinate de erori de program, de sistem, de echipament sau căderi de tensiune.
Starea consistenta (coerentă) a BD presupune că toate constrângerile impuse la definirea
logică a BD sunt respectate şi nu există date pierdute sau legături între tabele incomplete sau
incorecte (pointeri, sau referinte).
Toate prelucrarile trebuie să lase BD într-o stare consistentă. Secvenţele critice de comenzi
pot apare în timpul prelucrării şi pot aduce temporar BD într-o stare incosistentă.
Exemplu:
- transferul unor sume dintr-un cont în altul
- secvenţa de prelucrare a statului de plata pentru un salariat
- secventa de mărire a salariilor pentru toti angajaţii
Dacă apare un incident care opreşte programul într-o secventa critică, înainte de terminarea
ei, BD poate rămâne într-o stare inconsistentă (măriri de salarii numai pentru o parte din
angajaţi). Secventele critice trebuie grupate în tranzacţii marcate prin comanda COMMIT.
Tranzactia este o secvenţă de comenzi care pleacă dintr-o stare consistentă a BD şi ajunge
în altă stare consistentă. Intr-o tranzacţie BD poate trece temporar prin stări inconsistente. Din
acest motiv tranzacţia trebuie să se faca ori complet ori deloc. Sfârşitul corect al unei tranzacţii
se marchează prin comanda COMMIT care face ca modificările făcute să devină permanente.
Proiectarea Bazelor de Date
2
Toate valorile vechi ale înregistrărilor modificate în timpul tranzacţiei se memorează într-un
fişier de tranzacţii. Dacă pe timpul tranzacţiei apare un incident, starea BD se considera
inconsistentă şi reluarea prelucrării se va face obligatoriu prin comanda ROLLBACK.
Aceasta reface toate inregistrarile modificate de la inceputul tranzacţiei folosind vechile
valori citite din fisierul de tranzacţii. BD revine astfel la starea consistentă de la începutul
tranzacţiei. La sfârşitul unei tranzacţii prin COMMIT se sterge fişierul de tranzacţii şi
modificările devin definitive.
Există însă numeroase cauze care pot determina ca o bază de date să evolueze dintr-o stare
stabilă într-o stare instabilă ceea ce evident nu poate fi acceptat.
Caracteristicile tranzacţiei sunt Atomicitate, Consistenţă, Izolare, Durabilitate.
Atomicitatea se referă la faptul că o tranzacţie trebuie să se facă ori complet terminată cu
COMMIT) ori deloc, când se revine la starea de la începutul tranzacţiei prin executia
ROLLBACK.
Consistenţa: o tranzacţie trebuie să înceapă într-o stare consistentă a BD şi să se termine
lasând BD într-o sare consistentă.
Izolare: urmareşte asigurarea consistenţei citirii informaţiilor din BD.
Pe timpul tranzacţiei modificările făcute se vor vedea numai de user-ul care le-a executat.
Inregistrările modificate sunt blocate şi nu pot fi modificate de alţi useri, care ar putea determina
conflicte între modificările făcute de diferiţi useri.
Modificările făcute în tranzacţie vor fi vizibile pentru toţi user-ii numai la terminarea
tranzacţiei cu COMMIT. Pe timpul tranzacţiei înregistrările modificate pot fi citite de alţi
useri, dar valoarea lor este cea din momentul începerii tranzacţiei şi este luată din fişierul de
tranzacţii.
Durabilitea: la sfârşitul tranzacţiei, modificările făcute să fie permanente (durabile), lucru
care se realizează prin COMMIT care şterge fişierul de tranzacţii şi începe o nouă tranzacţie.
Pentru înţelegerea noţiunii de tranzacţie, vor fi considerate câteva exemple:
I. Presupunem a într-o relaţie R1(A, B, C) cu câteva mii de înregistrări valoarea din
coloana B trebuie mărită cu 20% în toate înregistrările. Dacă în timpul executării acestei operaţii
de actualizare din diverse motive sistemul cade, o parte din date vor fi actualizate în timp ce o
altă parte vor rămâne neactualizate. O astfel de situaţie nu poate fi acceptată. Remedierea unei
asemenea situaţii prin mijloacele clasice ale programării este foarte dificilă, deci vor trebui
utilizate mijloace speciale de protecţie care să asigure că operaţia de actualizare este ori realizată
pentru toate înregistrările ori nu se realizează deloc.
Cap. 5. Tranzacții
3
II. Presupunem că într-o bază de date există două relaţii R1 şi R2 având schemele R1(A,
B,…) respectiv R2(A, C, … ). În baza de date se impune următoarea regulă de integritate :
„Pentru orice valoare a din A, orice valoare v care se adună la B trebuie să fie scăzută din C.
Rezultatul scăderii trebuie să fie pozitiv. Dacă rezultatul scăderii este negativ nu se acceptă
operaţia de actualizare. ”
Evident, pentru realizarea operaţiei de actualizare a atributului B există mai multe variante
posibile:
a) citeşte B
B=B+v
scrie B
citeşte C
C=C-v
Dacă C≥0 scrie C.
b) citeşte B
citeşte C
B=B+v
C=C-v
scrie B
Dacă C≥0 scrie C.
c) citeşte C
C=C-v
Dacă C≥0 (scrie C
citeşte B
B=B-v
scrie B).
Dacă toate operaţiile decurg normal, în final trebuie să se ajungă pentru toate variantele
într-o stare S2 stabilă adică o stare pentru care B+C=constant şi C≥0.
Evoluţia dintr-o stare în alta se realizează în momentul scrierii într-o relaţie deoarece
numai scrierea modifică valorile atributelor care definesc starea bazei de date. Evoluţia stărilor
Fig. 5. 1 Exemplu de tranzacții
S1 Si S2
S1 Si S2
S1 Si S2
Scrie B
(C‐v≥0) Scrie C
B,C B+v, C B+v, C‐v, C>0
B,C B+v, C B+v, C‐v, C>0
B,C B, C‐v B+v, C‐v, C>0
Scrie B
Scrie B
(C‐v≥0) Scrie C
(C‐v≥0) Scrie C
C<0
Proiectarea Bazelor de Date
4
pentru fiecare dintre cele trei variante considerate este prezentată în figură. Se observă că în
fiecare caz în parte tranziţia implică trecerea printr-o stare instabilă Si în care numai o parte a
regulii de integritate este respectată. Stările S1 şi S2 sunt stări stabile. Vom prezenta câteva anomalii ce pot să apară în derularea procesului de actualizare a
datelor:
1) Presupunem că în fiecare caz, înăintea realizării primei scrieri apare o cădere a
sistemului. În acest caz conţinutul bazei de date nu este afectat şi baza de date rămâne în starea
stabilă S1.
2) Presupunem că sistemul cade după realizarea primei scrieri. În acest caz baza de
date rămâne în starea instabilă Si ceea ce reprezintă o eroare.
3) Sistemul funcţionează corect dar C-v<0. Pentru variantele a) şi b) acest lucru
conduce la plasarea bazei de date în starea instabilă Si, deci rezultatul este eronat. Pentru
varianta c) baza de date va rămâne în starea stabilă S1 ca şi cum nu ar fi avut loc nici o operaţie
asupra bazei de date (operaţiile de adunare şi scădere se realizează în memoria tampon deci nu
afectează conţinutul bazei de date).
Din analiza efectuată în exemplele 1 şi 2 se observă că în cazul în care prelucrarea datelor
implică mai multe operaţii de actualizare conectate logic printr-o regulă de actualizare a datelor,
pot să apară anomalii care conduc la plasarea bazei de date într-o stare instabilă ceea ce nu poate
fi acceptat. Tocmai pentru a evita astfel de situaţii a fost introdusă noţiunea de tranzacţie.
Prin tranzacţie se înţelege un set de operaţii de actualizare a conţinutului bazei de date,
conectate logic printr-o regulă de integritate, care ori se execută toate ori sunt anulate toate astfel
încât în final baza de date se va afla într-o stare stabilă indiferent ce evinimente apar pe durata
executării acestor operaţii.
III. Se presupune că asupra relaţiei R1(A, … ) se iniţializează simultan două tranzacţii T1
şi T2 de la doi utilizatori diferiţi, U1 şi U2. Fiecare tranzacţie trebuie să citească aceeaşi valoare
din A şi să înlocuiască vechea valoare cu valoarea A+10. Este evident că rezultatul corect după
realizarea celor două tranzacţii trebuie să fie A+20.
Se iau în considerare două scenarii pentru desfăşurarea celor două procese de actualizare a
datelor.
Scenariul de execuţie 1
Cap. 5. Tranzacții
5
Scenariul de execuţie 2
Fig.5.2 Exemplu de execuţie a două tranzacţii, cu rezultate finale diferite
Tranzacția 2
Tranzacția 1
Baza de date
Momentul de timp: T1 T2 T3 T4 T5 T6
Valoarea din Baza de date: 50 50 60 60 70 70
A=50 A=60 A=60
A=60 A=70 A=70
Citeşte A A=A+10 Scrie A
Citeşte A A=A+10 Scrie A
Tranzacția 2
Tranzacția 1
Baza de date
Momentul de timp: T1 T2 T3 T4 T5 T6
Valoarea din Baza de date: 50 50 50 60 60 60
A=50 A=60 A=60
A=50 A=60 A=60
Citeşte A A = A +10 Scrie A
Citeşte A A = A+10 Scrie A
Proiectarea Bazelor de Date
6
O asemenea situaţie în care rezultatul depinde de ordinea în care sunt executate tranzacţiile
(necontrolabilă de către utilizatori) nu poate fi acceptată. Concluzia care se impune în urma
analizei efectuate este accea că execuţia întreţesută a unor tranzacţii poate să conducă în anumite
situaţii la rezultate eronate deci cea mai simplă metodă de protecţie ar consta în executarea serie
a tranzacţiilor prin blocarea accesului la baza de date pe tot timpul execuţiei unei tranzacţii. Se
poate arăta (vezi exemplul E4) că aceasta este o condiţie suficientă dar nu neapărat necesară
pentru obţinerea unor rezultate corecte.
IV. Se consideră tranzacţia T1 care execută operaţia A=A+1 pentru valoarea lui A din
înregistrarea 1 şi tranzacţia T2 care execută aceeaşi operaţie asupra valorii lui A din înregistrarea
2. Se consideră execuţia întreţesută a celor două tranzacţii după următorul scenariu:
Fig.5.3 Exemplu de execuţie a două tranzacţii care nu utilizează acelaşi set de date
In cazul în care tranzacţiile nu afectează aceleaşi date, nu are importanţă în ce ordine se
execută actualizarea datelor.
Tranzacția 2
Tranzacția 1
Baza de date
Momentul de timp: T1 T2 T3 T4 T5 T6
Valoarea din A(Inreg1) 50 50 60 60 60 60Baza de date: A(Inreg2) 50 50 50 50 60 60
A=50 A=60 A=60
A=60 A=70 A=70
Citeşte A A=A+10 Scrie A
Citeşte A A=A+10 Scrie A
Cap. 5. Tranzacții
7
Există multe alte situaţii care pun în evidenţă necesitatea utilizării unor mijloace speciale
de gestiune a tranzacţiilor pentru a asigura pe de o parte integritatea datelor iar pe de altă parte o
execuţie optimă a tranzacţiilor în sensul scăderii timpului de servire a tranzacţiilor.
Proprietăţile tranzacţiilor
Toate tranzacţiile, indiferent de operaţiile pe care le realizează trebuie să posede
următoarele caracteristici:
• Atomicitatea - Atomicitatea tranzacţiei presupune că toate operaţiile specifice unei
tranzacţii trebuie tratate ca o unitate logică indivizibilă adică ori se execută toate
operaţiile ori nu se execută niciuna. Cu alte cuvinte eşecul unei singure operaţii din
ansamblul de operaţii care formează tranzacţia implică eşecul întregii tranzacţii.
Această proprietate decurge din însăşi definiţia tranzacţiei.
• Consistenţa - Consistenţa tranzacţiei se referă la faptul că aceasta trebuie să păstreze
invariantă o anumită regulă de integritate indiferent de condiţiile în care se desfăşoară
tranzacţia.
De exemplu regula “suma dintre numărul pieselor eliberate din magazie şi
numărul pieselor rămase trebuie să fie egal cu numărul pieselor intrate în evidenţă în
acelaşi interval de timp” va trebui să fie respectată în orice moment de timp chiar dacă au
fost înregistrate căderi ale sistemului atât în regim monoutilizator cât şi în regim
multiutilizator.
Utilizarea conceptului de tranzacţie va rezolva această problemă deoarece
utilizatorii vor percepe tranzacţia ca pe un tot unitar, ne-având acces la rezultatele
intermediare ci numai la cele finale când restricţia este întotdeauna respectată fie că
tranzacţia s-a desfăşurat normal şi baza de date a trecut într-o nouă stare stabilă în raport
cu restricţia impusă fie că tranzacţia a eşuat şi baza de date a rămas în vechea stare de
asemenea stabilă în raport cu restricţia impusă.
• Independenţa - Independenţa tranzacţiilor impune ca rezultatul executării operaţiilor ce
compun o tranzacţie să fie consistent indiferent de tranzacţiile cu care interacţionează în
timpul execuţiei sau de momentul interacţiunii.
Proiectarea Bazelor de Date
8
Proprietatea se referă la un context în care mai multe tranzacţii lucrează simultan
asupra aceluiaşi set de date ceea ce presupune execuţia concurentă a mai multor
programe. În acest caz un program nu trebuie să aibă acces la rezultatele parţiale ale altui
program deoarece rezultatele finale ar putea fi dependente de momentul interacţiunii
programelor.
• Durabilitatea - Durabilitatea implică păstrarea rezultatelor unei tranzacţii nealterate chiar
şi în cazul căderii sistemului (evident, dacă nu a fost distrus suportul de memorie
externă). Aceasta implică păstrarea rezultatelor unei tranzacţii într-o structură de date
persistentă ceea ce reprezintă de fapt o caracteristică fundamentală a oricărei aplicaţii
asupra bazelor de date. Cu alte cuvinte orice tranzacţie trebuie să se încheie normal prin
modificarea conţinutului bazei de date cu respectarea regulii de integritate impusă. În caz
de eşec conţinutul bazei de date nu se va modifica, ca şi cum nimic nu s-ar fi întâmplat.
Utilizarea structurilor de date persistente face ca utilizarea tranzacţiilor să difere
fundamental de programele care lucrează cu date în memoria principală a calculatorului.
Beneficii din folosirea tranzacţiilor. Menţinerea consistenţei logice a bazei de
date.
Din cele prezentate anterior se observă că utilizarea tranzacţiilor poate rezolva mai multe
probleme şi anume:
1) creşterea vitezei de lucru a sistemului;
2) menţinerea consistenţei logice a conţinutului bazei de date chiar în cazul căderii
sistemului;
3) eliminarea anomaliilor specifice execuţiei concurente a două sau mai multe
programe care afectează acelaşi set de date.
Deşi în SGBD moderne cele trei aspecte sunt rezolvate împreună, din motive metodologice
ele vor fi prezentate separat.
Ca orice sistem fizic şi sistemul de calcul este supus unor funcţionări eronate sau chiar
căderii irecuperabile ale unor subsisteme. Din această cauză este necesar să fie luate măsuri
speciale pentru a preveni sau cel puţin pentru a limita pierderile de informaţie datorate unor erori
Cap. 5. Tranzacții
9
de funcţionare. Printre metodele utilizate în acest scop, utilizarea tranzacţiilor ocupă un loc
deosebit de important cel puţin în cazul următoarelor tipuri de erori:
1) erori logice (logical errors) - atunci când programul nu poate continua execuţia
normală datorită unor anomalii cum ar fi lipsa datelor specificate, împărţire la 0, depăşiri
de format, incompatibilitatea tipului datelor, insuficienţa memoriei principale, umplerea
discului etc.
2) erori de sistem (system errors) – atunci când sistemul intră într-o stare de blocare
(deadlock) ceea ce împiedică executarea normală a programului; programul va putea fi
reluat şi executat normal într-un alt context.
3) căderi de sistem (sistem crash) – datorate unor defecte hardware ce conduc la
pierderea conţinutului memoriei principale fără însă a afecta ireversibil conţinutul
memoriei secundare.
4) căderea discului (disck failed) – dacă din diverse motive este afectat suportul
memoriei secundare şi conţinutul său devine inaccesibil.
Operaţii de intrare/ieşire în bazele de date
Se va considera în continuare că baza de date este păstrată numai pe disc ceea ce
corespunde în bună măsură situaţiei actuale.
Baza de date este împărţită în unităţi de lungime fixă numite blocuri (blocks). Un bloc este
unitatea de bază atât în procesul de alocare a memoriei cât şi în procesele de transfer a datelor.
Toate operaţiile de citire şi de scriere sunt realizate prin manipularea unui număr întreg de
blocuri. Blocurile păstrate pe disc se numesc blocuri fizice (physical blocks) în timp ce blocurile
rezidente în memoria principală sunt desemnate ca blocuri tampon (buffer blocks).
Deplasarea informaţiei între disc şi memoria principală se realizează de către SGBD prin
două operaţii notate simbolic:
1) input(X) – operaţia care transferă blocul fizic care conţine înregistrarea sau câmpul X,
în memoria pincipală;
Proiectarea Bazelor de Date
10
2) output(X) – operaţia prin care blocul tampon în care se află înregistrarea sau câmpul
X, în blocul corespunzător de pe disc.
Grafic, efectul celor două operaţii este prezentat în figura următoare
Programele aplicative interacţionează cu baza de date prin alte două operaţii notate
simbolic:
a) read (X,xi) – operaţia prin care valoarea înregistrării sau câmpului X este alocată
variabilei xi; execuţia acestei operaţii presupune două etape:
1) dacă blocul în care se află X nu se găseşte deja în memoria principală se va iniţia
o operaţie input(X);
2) valoarea lui X din blocul tampon este asignată variabilei locale xi.
b) write(X,xi) – operaţia prin care valoarea variabilei locale xi este este asignată
elementului X din blocul tampon; Execuţia acestei operaţii presupune două etape:
1) dacă blocul în care se află X nu se găseşte deja în memoria principală se va iniţia
o operaţie input(X);
2) valoarea variabilei locale xi este asignată lui X în blocul tampon.
Se observă imediat că atât read (X,xi) cât şi write (X,xi) pot iniţia eventual o operaţie
input(X) dar nici una nu lansează în execuţie operaţia output(X). Aceasta înseamnă că de fapt
programul aplicativ nu poate modifica direct conţinutul bazei de date. Transferul de date din
B A
OUTPUT B
INPUT A
Memorie Baza de Date
Fig. 5. 4 Executarea celor 2 operații
Cap. 5. Tranzacții
11
memoria tampon pe disc (în baza de date) este comandat de SGBD. Această strategie pentru
actualizarea conţinutului bazei de date are ca principal avantaj reducerea semnificativă a
numărului de accese la memoria secundară şi în consecinţă creşterea vitezei globale de lucru.
Pe de altă parte însă, între momentul actualizării datelor de către aplicaţie prin write(X,xi) şi
momentul scrierii pe disc a noilor valori prin output(X) poate să existe un interval de timp uneori
semnificativ. Dacă în acest interval apare o eroare ce conduce la întreruperea programului, baza
de date nu va mai putea fi actualizată şi efectul programului aplicativ este pierdut.
Stările unei tranzacţii
Pentru a înţelege cum funcţionează o tranzacţie în scopul menţinerii unei baze de date
permanent într-o stare stabilă, se va considera următorul model simplificat al unei tranzacţii, care
pune în evidenţă principalele stări ce caracterizează evoluţia acesteia. Diagrama de tranziţie a
stărilor este prezentată în figura 5.5.
Stările puse în evidenţă au următoarele semnificaţii:
• Starea activă (active) – este starea iniţială a oricărei tranzacţii; pe durata stării active se
execută programul aferent trazacţiei.
• Starea parţial realizată (partialy commited) – este starea în care trece tranzacţia după ce
a fost executată cu succes ultima instrucţiune din programul aferent. În această stare
Fig. 5. 5 Evoluția execuției unei trnazacții
Parțial realizată
activă
Finalizată
Eşuată
Abandonată
Proiectarea Bazelor de Date
12
programul a fost executat normal dar rezultatele prelucrărilor nu sunt integral salvate pe
disc deci pot să mai apară situaţii care să conducă la eşuarea tranzacţiei.
• Starea eşuată (failed) apare după ce se constată că din diverse motive (lipsa unor date în
baza de date, operaţii imposibile, depăşiri de format, lipsă de spaţiu pe disc, căderea
discului etc) execuţia normală sau salvarea datelor pe disc nu mai pot continua.
• Starea abandonată (aborted) – corespunde momentului în care, după întreruperea
execuţiei normale, baza de date a fost adusă în starea stabilă anterioară lansării în
execuţie a tranzacţiei deci se garantează că tranzacţia nu a avut nici un efect asupra
bazei de date. Evident, acest lucru nu este posibil dacă eşuarea tranzacţiei s-a datorat
unei căderi de sistem sau de disc care fac imposibilă refacerea conţinutului bazei de
date numai prin mecanismul tranzacţiilor.
Când tranzacţia ajunge în această stare, SGBD are două posibilităţi:
Reexecuţia tranzacţiei (restart the transaction).
Această soluţie are sens numai dacă abandonul a survenit în urma unei erori
hardware sau de sistem dar nu are sens dacă eroarea se datorează logicii
programului aferent tranzacţiei sau unor caracteristici ale datelor.
Distrugerea tranzacţiei (kill the transaction).
Această soluţie se alege întotdeauna când eroarea poate fi corectată numai
prin rescrierea programului aferent tranzacţiei.
• Starea realizată (commited) marchează încheierea cu succes a tuturor operaţiilor ce
formează tranzacţia şi salvarea pe disc a tuturor modificărilor implicate de acestea.
După trecerea în această stare, tranzacţia este încheiată iar baza de date se află într-o nouă
stare stabilă. Intrarea în starea “realizată” garantează că toate datele au fost generate corect
conform logicii programului şi că orice s-ar întâmpla în continuare datele generate nu vor
fi pierdute.
Utilizarea fişierului log incremental pentru reconstituirea bazei de date
Există mai multe metode care garantează că datele generate înăinte de intrarea în starea
“realizată” nu vor fi pierdute decât în cazul căderii sistemului.
Metodele de siguranţă includ în primul rând folosirea fişierului log.
Utilizarea fişierului log incremental cu actualizare întârziată
Cap. 5. Tranzacții
13
Evident, orice eşec al unei tranzacţii va conduce la încălcarea integrală sau parţială a unor
reguli de integritate a datelor sau chiar la pierderea unor date. Datorită acestui lucru a fost
introdus un fişier special numit fişierul log (fişierul jurnal) al bazei de date care are ca unic scop
păstrarea tuturor rezultatelor parţiale ale tranzacţiilor, care nu au fost încă transferate în baza de
date, pentru a putea reconstitui conţinutul bazei de date în cazul eşecului tranzacţiei.
Una din strategiile posibile de execuţie a tranzacţiei Ti este următoarea:
• Înăinte de lansarea în execuţie a tranzacţiei Ti în fişierul log se înscrie o înregistrare de
forma < Ti starts> .
• Pe durata execuţiei tranzacţiei, fiecare operaţie write(X, xj) implică scrierea unei noi
înregistrări în fişierul log. Fiecare dintre aceste înregistrări va avea o structură de forma <Ti , X,
xj> unde:
� Ti – numele tranzacţiei în curs de execuţie;
� X – numele câmpului actualizat;
� xj – valoarea nouă a lui X adică valoarea curentă a variabilei xj.
• Când tranziţia Ti trce în starea “parţial realizată”, în fişierul log se înscrie o înregistrare cu
structura < Ti commits>. Numai după ce a fost înscris în fişierul log această înregistrare, fişierul
log poate fi utilizat pentru actualizarea bazei de date.
Se observă imediat că între momentul în care în fişierul log este înscrisă ultima înregistrare şi
momentul în care baza de date este efectiv actualizată poate să treacă destul de mult timp. În
acest interval pot să apară căderi ale sistemului sau discului care să ducă la eşecul tranzacţiei.
Din această cauză tranzacţia trece în starea “realizată” şi execuţia ei se consideră încheiată numai
după ce toate modificările în conţinutul bazei de date au fost transferate cu succes pe disc, deci
baza de date se află într-o nouă stare stabilă.
Exemplu: Pentru a înţelege mecanismul de protecţie a bazei de date prezentat anterior, se
vor considera două tranzacţii T0 respectiv T1 care sunt executate secvenţial. Structura
tranzacţiilor este prezentată în figura 6.7. Se presupune că iniţial A, B şi C au valorile 100, 200
respectiv 300. În figura 6.8a este prezentată secvenţa de înregistrări din fişierul log generată de
execuţia cu succes a celor două tranzacţii.
T0: read(A,a1)
a1:=a1-10
write (A,a1)
Proiectarea Bazelor de Date
14
read(B, b1)
b1:=b1+10
write (B,b1)
T1: read(C,c1)
c1:=c1-100
write (C,c1)
Fig. 6.7
<T0 starts>
<T0, A, 90>
<T0, B, 210>
<T0 commits>
<T1 starts>
<T1, C, 200>
<T1 commits>
a)
<T0 starts>
<T0, A, 90>
<T0, B, 210>
b)
<T0 starts>
<T0, A, 90>
<T0, B, 210>
<T0 commits>
<T1 starts>
Cap. 5. Tranzacții
15
<T1, C, 200>
c)
Fig. 6.8
Pentru cazul în care toate operaţiile se desfăşoară normal, fără erori de sistem sau căderi de disc,
evoluţia în timp a conţinutului fişierului log, conţinutului bazei de date şi a stării tranzacţiilor
este prezentată în figura 6.9.
Pentru a înţelege cum se utilizează fişierul log pentru menţinerea bazei de date într-o stare
stabilă se vor considera câteva scenarii de apariţie a erorilor:
Conţinut
fişier log Scrieri în baza de date Baza de date Starea tranzacţiei
A B C
t0 <T0 starts> 100 200 300 activă
t1 <T0, A, 90> 100 200 300 activă
t2 <T0, B, 210> 100 200 300 activă
t3 <T0 commits> 100 200 300 parţial realizată
t4 output(A) 90 200 300 parţial realizată
t5 output(B) 90 210 300 realizată
t6 <T1 starts> 90 210 300 activă
t7 <T1, C, 200> 90 210 300 activă
t8 <T1 commits> 90 210 300 parţial realizată
t9 output(C) 90 210 200 realizată
Fig. 6.9
a) Eroarea de sistem apare între momentele t¬2 şi t3 .
Conţinutul fişierului log este prezentată în figura 6.8b .
Deoarece la reluare se găseşte <T0 starts> dar nu se găseşte <T0 commits>, nu se iniţializează
nici un transfer de date către baza de date deci baza de date rămâne în starea stabilă iniţială, ca şi
cum tranzacţia nu ar fi avut loc.
Proiectarea Bazelor de Date
16
b) Eroarea de sistem apare între momentele t4 şi t5.
La reluare, în fişierul log se găsesc şi <T0 starts> şi <T0 commits> şi pentru a asigura
integritatea conţinutului bazei de date este obligatoriu să se reia scrierea tuturor datelor în baza
de date. Operaţia de rescriere a datelor în baza de date se numeşte redo(T0).
În cazul analizat A fusese actualizat dar procedura cere actualizarea tuturor câmpurilor deoarece
nu se marchează care câmpuri au fost actualizate şi care nu.
După execuţia fără erori a operaţiei redo(T0) baza de date se află într-o nouă stare stabilă.
c) Eroarea de sistem apare între momentele t7 şi t8.
Conţinutul fişierului log este prezentată în figura 6.8c .
La reluare, în fişierul log se găsesc şi <T0 starts> şi <T0 commits> şise reia scrierea în baza de
date pentru rezultatele acestei tranzacţii. Deoarece lipseşte <T1 commits>, rezultatele tranzacţiei
T1 sunt neglijate deci baza de date va rămâne în starea stabilă corespunzătoare finalizării cu
succes a tranzacţiei T0.
d) Eroarea de sistem apare între momentele t8 şi t9.
La reluare sistemul citeşte conţinutul fişierului log şi constată că există atât <T0 commits> cât şi
<T1 commits> deci se execută redo(T0) şi redo(T1) a căror finalizare cu succes asigură trecerea
bazei de date într-o nouă stare stabilă.
e) În timpul operaţiei redo(T0) apare din nou o eroare de sistem.
La reluare sistemul acţionează ca şi cum nimic nu s-ar fi întâmplat, citeşte conţinutul fişierului
log şi execută toate operaţiile redo implicate de acesta pentru a garanta starea stabilă a bazei de
date.
Concluzie: Indiferent când apare o eroare de sistem, repornirea sistemului implică citirea
automată a fişierului log şi executarea unei operaţii redo(Ti) pentru toate tranzacţiile care au
înscris <Ti commits>. Pentru celelalte tranzacţii nu se execută nici o operaţie de transfer pe
disc, ca şi cum aceste tranzacţii nu s-ar fi executat niciodată, deoarece din diverse motive ele nu
au reuşit să ajungă în starea “parţial realizată” deci nu există garanţia că toate operaţiile aferente
au fost executate cu succes.
6.4.2 Utilizarea fişierului log incremental cu actualizare imediată
Cap. 5. Tranzacții
17
Spre deosebire de cazul precedent, orice operaţie write(X, xj) este urmată imediat de o operaţie
output(X) ceea ce implică modificarea conţinutului bazei de date chiar pe durata execuţiei
tranzacţiei.
Complectarea fişierului log presupune următoarele etape:
• Înăinte de lansarea în execuţie a tranzacţiei Ti în fişierul log se înscrie o înregistrare de
forma < Ti starts> .
• Pe durata execuţiei tranzacţiei, fiecare operaţie write(X, xj) implică scrierea unei noi
înregistrări în fişierul log. Fiecare dintre aceste înregistrări va avea o structură de forma <Ti , X,
xv, xj> unde:
� Ti – numele tranzacţiei în curs de execuţie;
� X – numele câmpului actualizat;
� xv – valoarea veche a lui X adică valoarea citită din baza de date înăintea modificării de
către program;
� xj – valoarea nouă a lui X adică valoarea curentă a variabilei xj.
• Când tranziţia Ti trce în starea “parţial realizată”, în fişierul log se înscrie o înregistrare cu
structura < Ti commits>. Numai după ce a fost înscris în fişierul log această înregistrare, fişierul
log poate fi utilizat pentru actualizarea bazei de date.
Observaţie: Deoarece fişierul log este utilizat pentru refacerea conţinutului bazei de date în
cazul eşecului tranzacţiei, nici o operaţie output(X) nu este admisă până când înregistrarea
aferentă lui X nu a fost înscrisă în fişierul log. În caz contrar ar apare în baza de date o
modificare ce nu ar putea fi eliminată în cazul în care căderea sistemului apare imediat după
execuţia lui output(x) şi înăintea transcrierii în fişierul log.
Pentru a înţelege modul de utilizare al fişierului log în noua strategie, se consideră aceleaşi două
tranzacţii T0 şi T1 din figura 6.7, executate în aceeaşi ordine şi cu valori iniţiale în baza de date.
Conţinutul fişierului log după execuţia cu succes a celor două tranzacţii este prezentată în figura
6.10.
<T0 starts>
<T0, A, 100, 90>
Proiectarea Bazelor de Date
18
<T0, B, 200, 210>
<T0 commits>
<T1 starts>
<T1, C, 300, 200>
<T1 commits>
Fig. 6.10
Utilizând acest fişier log Sgbd poate rezolva orice eroare care nu are ca efect distrugerea
suportului de memorie secundară. Refacerea informaţiei se realizează cu ajutorul a două
proceduri:
• undo(Ti) care anulează efectul tuturor actualizărilor realizate anterior şi aduce baza de date
în starea stabilă iniţială.
• redo(Ti) care asigură transferul în baza de date a tuturor valorilor noi generate de operaţiile
specifice tranzacţiei Ti.
Operaţiile undo şi redo trebuie să fie idempotente în sensul garantării unui rezultat corect chiar
dacă apare o cădere de sistem pe timpul operaţiei de refacere a bazei de date.
Pentru a rezolva refacerea conţinutului bazei de date, la repornirea sistemului după apariţia unei
erori, sistemul citeşte fişierul log pentru a determina care dintre cele două proceduri se va aplica
pentru fiecare dintre tranzacţiile executate anterior.
Operaţia este aleasă după următoarea regulă:
• Se execută undo(Ti) dacă în fişierul log apare înregistrarea <Ti starts> dar nu apare
înregistrarea <Ti commits>.
• Se execută undo(Ti) dacă fişierul log conţine atât înregistrarea <Ti starts> cât şi
înregistrarea <Ti commits>.
Pentru a înţelege cum funcţionează sistemul pe baza acestei strategii, în figura 6.11 se prezintă
derularea în timp a operaţiilor de actualizare a fişierului log şi a bazei de date în condiţii
normale.
Conţinut
fişier log Scrieri în baza de date Baza de date Starea tranzacţiei
A B C
t0 <T0 starts> 100 200 300 activă
Cap. 5. Tranzacții
19
t1 <T0, A, 100, 90> 100 200 300 activă
t2 output(A) 90 200 300 activă
t3 <T0, B, 210> 90 200 300 activă
t4 output(B) 90 210 300 parţial realizată
t5 <T0 commits> 90 210 300 realizată
t6 <T1 starts> 90 210 300 activă
t7 <T1, C, 300, 200> 90 210 300 activă
t8 output(C) 90 210 300 parţial realizată
t9 <T1 commits> 90 210 200 realizată
Fig. 6.11
În continuare vor fi analizate diverse scenarii de apariţie a erorilor şi modul de rezolvare a
reconstituirii conţinutului bazei de date în caz de eroare.
a ) Eroarea apare între momentele t2 şi t5. În acest caz în fişierul log se gaseşte <T0 starts> dar
nu există <T0 commits>. În baza de date a fost actualizat doar câmpul A dacă eroarea apare între
t2 şi t4 sau atât câmpul A cât şi B dacă eroarea apare între t4 şi t5. Deoarece nu există o garanţie
a inyegrităţii conţinutului bazei de date, este natural ca folosind informaţiile din fişierul log baza
de date să fie adusă în starea stabilă iniţială prin realizarea unei operaţii undo(T0).
b) Eroarea apare între momentele t6 şi t9. În acest caz pentru tranzacţia T0 în fişierul log se
găsesc atât <T0 starts> cât şi <T0 commits> deci fişierul log conţine toate informaţiile necesare
refacerii conţinutului bazei de date. Pentru tranzacţia T1 apare numai <T1 starts> deci nu se
garantează încheierea cu succes a realizării tranzacţiei. În consecinţă, la reluarea execuţiei după
eliminarea erorii, sistemul va executa automat operaţiile redo(T0) şi undo(T1).
c) Dacă în timpul unei operaţii redo(Ti) sau undo(Ti) apare din nou o eroare, la repornire
sistemul va citi din nou conţinutul fişierului log şi în consecinţă va relua procesul de
reconstituire a conţinutului bazei de date ca şi cum nimic nu s-ar fi întâmplat.
În concluzie, utilizarea fişierului log permite reconstituirea conţinutului bazei de date în toate
sitoaţiile care nu conduc la distrugerea suportului fizic al acesteia sau la deteriorarea fişierului
log.
Proiectarea Bazelor de Date
20
Având în vedere importanţa cu totul deosebită a fişierului log, se recomandă ca acesta să fie
păstrat în cel puţin două copii pe suporturi fizice diferite pentru ca probabilitatea distrugerii
simultane a ambelor copii să fie cât mai mică cu putinţă.
6.4.3 Puncte de control (Checkpoints)
Procedeul prezentat anterior necesită ca la fiecare repornire a sistemului să fie analizat întreg
conţinutul fişierului log pentru a stabili care tranzacţie trebuie să fie refăcută (redo(Ti)) şi pentru
care tranzacţie trebuie anulate efectele (undo(Tj)). Această strategie prezintă două inconveniente
majore:
• Procesul de căutare este în cazul unor baze de date mari, cu mii de tranzacţii pe unitatea de
timp, mare consumator de timp ceea ce va întârzia semnificativ repornirea sistemului.
• Multe dintre tranzacţiile pentru care se ia hotărârea redo(Ti) şi-au transmis integral efectul
către baza de date deci rescrierea informaţiei chiar dacă nu este dăunătoare, este inutilă şi
prelungeşte nejustificat timpul de reconstituire a conţinutului bazei de date.
Pentru a elimina aceste neajunsuri, a fost introdus conceptul de punct de control care implică
următoarea secvenţă de operaţii:
1) Toate înregistrările log rezidente în memoria principală a calculatorului sunt transferate pe
disc în fişierul log;
2) Toate blocurile tampon afectate de modificări sunt transferate pe disc;
3) În fişierul log se înscrie înregistrarea <checkpoint>.
Utilizând acest concept, mecanismul de reconstituire a conţinutului bazei de date poate fi
îmbunătăţit în sensul celor specificate mai jos.
După apariţia unei căderi, la repornire SGBD examinează fişierul log în scopul determinării
ultimei tranzacţii a cărei început se situează înăintea ultimului <checkpoint> înscris în fişierul
log. Pentru aceasta fişierul log este citit în sens invers şi se caută de fapt primul <Ti starts> după
primul <checkpoint> găsit.
În continuare, operaţiile redo(Tj) şi undo(Tj) se vor aplica numai pentru tranzacţiile Tj j≥i.
Cap. 5. Tranzacții
21
Exemplu: Se presupune că în fişierul log sunt păstrate înregistrări privind tranzacţiile {T0,
T1 … T100}. Dacă punctul de control a fost plasat pe durata tranzacţiei T70 atunci la repornirea
după o cădere a sistemului, reconstituirea informaţiei din baza de date prin operaţiile undo(Ti) şi
redo(Ti) va fi necesară numai pentru tranzacţiile {T70 … T100}. Strategia de realizare a
operaţiilor checkpoint este specifică fiecărui SGBD,
6.4.4 Influenţa gestiunii memoriei tampon asupra utilizării tranzacţiilor
Tacit, în modelul prezentat anterior pentru tranzacţii s-a considerat că ori de câte ori se execută o
operaţie input(X), în memoria principală există suficient spaţiu pentru noul bloc citit. În
sistemele reale acest lucru nu este întotdeauna adevărat. Pentru sistemele de operare moderne
care utilizează memoria virtuală, problema este rezolvată prin evacuarea pe disc a unor blocuri
neutilizate în momentul respectiv şi înlocuirea lor cu blocurile necesare. Această strategie de
transfer a datelor pe disc în baza de date în timpul execuţiei unei tranzacţii intră în conflict
evident cu strategia discutată pentru reconstituirea conţinutului bazei de date deoarece pot să
apară în caz de eşec înregistrări noi în baza de date neluate în evidenţă printr-o înregistrare în
fişierul log. Din această cauză se impune o condiţie suplimentară şi anume ca toate înregistrăâile
din fişierul log aferente unui bloc tampon să fie transferate în fişierul log pe disc înainte de a
transfera în baza de date blocurile considerate inutile în momentul respectiv. În caz contrar este
posibil ca în baza de date să existe actualizări care nu vor putea fi anulate printr-o operaţie
redo(Ti) deci baza de date va rămâne într-o stare instabilă.
Exemplu: Se consideră tranzacţia T1 descrisă anterior (Fig. 6.8). Presupunem că în
momentul în care apare necesitatea eliberării spaţiului în memoria principală, imaginea
blocurilor în memoria principală şi pe disc este cea din figura 6.12. dacă imediat după transferul
blocului B1 apare o cădere a sistemului, conţinuturile blocurilor din memoria principală şi de pe
disc vor fi cele din figura 6.13.
Se observă imediat că în acest caz înregistrările din fişierul log nu reflectă modificările din baza
de date deci nu se poate realiza o operaţie redo(Ti) eficientă.
În concluzie se poate formula următoarea regulă:
Proiectarea Bazelor de Date
22
Înăinte de a executa o operaţie de transfer a unui bloc tampon în fişierul bazei de date, este
obligatoriu să fie transferate pe disc în fişierul log toate blocurile care conţin informaţii
referitoare la tranzacţiile în curs de execuţie. Numai după actualizarea fişierului log este permisă
actualizarea bazei de date.
Fig. 6.12
Fig. 6.13
6.5 Creşterea performanţelor aplicaţiilor
Tranzacţiile pot fi utilizate în anumite condiţii pentru creşterea vitezei de lucru a
aplicaţiilor. Aceasta se realizează prin păstrarea în memoria principală a tuturor rezultatelor
programului aplicativ şi transferarea lor numai după ce programul a fost executat în întregime. În
felul acesta se reduce numărul acceselor la memoria secundară ceea ce va creşte în final viteza
de rezolvare a problemei. Principala condiţie care trebuie satisfăcută este existenţa unui volum
suficient de memorie liberă astfel încât să nu apară necesitatea unor transferuri intermediare pe
disc ceea ce ar reduce mult eficienţa metodei.
6.6 Controlul concurenţei (concurrency control)
6.6.1 Prezentare generală
Unul dintre cele mai importante concepte în calculatoarele moderne îl reprezintă
multiprogramarea, implementată în două variante complementare:
• pentru sisteme noninteractive (batch systems);
• pentru sisteme interactive (time-sharing systems).
Cap. 5. Tranzacții
23
La ora actuală prezintă interes deosebit sistemele interactive care permit execuţia
“simultană” a mai multor tranzacţii ceea ce scurtează foarte mult timpul de răspuns în cazul unor
tranzacţii scurte (la cel mult câteva secunde). Întreţeserea execuţiei tranzacţiilor permite o
folosire mult mai bună a timpului de lucru al procesoarelor eliminând în bună măsură timpii de
aşteptare pentru execuţia unor operaţii de intrare/ieşire.
Execuţia concurentă a mai multor programe care interacţionează cu aceeaşi bază de date
poate însă să conducă la apariţia unor efecte nedorite de pierdere a consistenţei bazei de date prin
încălcarea unor reguli de integritate a conţinutului bazei de date. Se impune deci utilizarea unor
mecanisme speciale de control a concurenţei în scopul menţinerii bazei de date într-o stare
stabilă. În continuare vor fi prezentate câteva din metodele de bază utilizate în acest scop.