4.9.Tranzacții, încuietori și acces la date pentru mai mulți utilizatori.
Orice bază de date este utilizabilă numai atunci când starea acesteia corespunde stării domeniului. Astfel de state se numesc integrale. Evident, atunci când schimbăm date, baza de date trebuie să treacă de la o stare holistică la alta. Cu toate acestea, în procesul de actualizare a datelor, sunt posibile situații în care starea integrității este încălcată. De exemplu:- În sistemul bancar, fondurile sunt transferate de la un cont la altul. În SQL, această operație este descrisă de secvența a două comenzi UPDATE. După cum puteți vedea, după prima echipă și echipa a doua pentru a completa baza de date nu este într-o stare consistentă (cantitatea necesară dedusă din primul cont, dar nu sunt creditate de-al doilea). Dacă în acest moment sistemul nu reușește (de exemplu, opriți alimentarea), atunci întreaga stare a bazei de date va fi pierdută iremediabil.
- Integritatea bazei de date poate fi, de asemenea, încălcată în timpul procesării unei singure comenzi SQL. Să presupunem că se realizează operarea creșterii salariului tuturor angajaților companiei cu 20%: în acest caz, DBMS procesează secvențial toate înregistrările care trebuie să fie actualizate, adică există un interval de timp în care unele înregistrări conțin valori noi, iar altele sunt cele vechi.
Pentru a evita astfel de situații, DBMS introduce noțiunea de tranzacție - o acțiune atomică pe o bază de date care o transferă dintr-o stare holistică într-o altă stare integrată. Cu alte cuvinte, o tranzacție este o secvență de operații care trebuie fie completate, fie toate nerealizate (toate sau nimic).
Metoda de control al tranzacțiilor este logarea. care înregistrează toate modificările efectuate de tranzacție în baza de date. Dacă tranzacția eșuează în timpul procesării tranzacției, tranzacția este reluată - starea bazei de date este restabilită din jurnal atunci când începe tranzacția.
În diferiți furnizori, începutul unei tranzacții poate fi specificat în mod explicit (de exemplu, cu comanda BEGIN TRANSACTION) sau poate fi implicit (așa cum este definit în standardul SQL), adică Următoarea tranzacție se deschide automat imediat după finalizarea reușită sau nereușită a celei anterioare. Pentru a finaliza o tranzacție, utilizați de obicei comenzi SQL:- COMMIT - finalizarea cu succes a tranzacției
- ROLLBACK - tranzacție de revocare, adică Returnați baza de date în starea în care a fost în momentul în care a început tranzacția.
- instrucțiunea COMMIT indică finalizarea cu succes a tranzacției, toate modificările făcute în baza de date sunt făcute permanente
- instrucțiunea ROLLBACK anulează tranzacția și anulează toate modificările efectuate
- finalizarea cu succes a programului care a inițiat tranzacția înseamnă finalizarea cu succes a tranzacției (cum ar fi utilizarea COMMIT)
- o terminare eronată a programului termină tranzacția (ca ROLLBACK)
- Dirty Read - tranzacția T1 a modificat un element de date. Apoi, o altă tranzacție T2 a citit conținutul acestui element de date înainte ca tranzacția T1 să fi fost terminată. Dacă T1 este omorât prin operația ROLLBACK. atunci se pare că tranzacția T2 a citit datele inexistente.
- Non-repetabil sau Fuzzy Read - tranzacția T1 a citit conținutul elementului de date. După aceasta, o altă tranzacție T2 a modificat sau a șters acest element. Dacă T1 citește conținutul acestui element, va obține o valoare diferită sau va constata că elementul de date nu mai există.
- Phantom (Phantom) - tranzacția T1 a citit conținutul mai multor elemente de date care satisfac o anumită condiție. După aceasta, T2 a creat un element de date care satisface această condiție și este fixat. Dacă T1 repetă citirea cu aceeași condiție, va primi un alt set de date.
Toate situațiile descrise mai sus au apărut numai pentru că nu a fost comandată executarea alternativă a tranzacțiilor T1 și T2, adică nu era echivalentă cu efectuarea primei tranzacții T1, apoi a T2 sau, invers, a primei tranzacții T2, apoi a T1.
Comanda forțată a tranzacțiilor este asigurată de mecanismul de blocare. Esența mecanismului este după cum urmează: în cazul în care punerea în aplicare a unei tranzacții presupune că un anumit obiect bază de date (set tuplu de tupluri, atitudinea, un set de relații.) Nu a schimbat impredictibil și fără cunoașterea acestei tranzacții, obiectul este blocat. Principalele tipuri de încuietori sunt:- blocare interlock. Se mai numește și un S-lock (de la încuietori partajate) și un bloc de citire.
- blocare exclusivă (fără acces reciproc), denumită și X-lock de la (încuietori eXclusive) sau dezactivată pentru scriere. Acest mod este utilizat pentru operațiile de modificare, adăugare și ștergere a obiectelor.
- dacă tranzacția impune un blocaj X pe obiect, atunci orice cerere pentru o altă tranzacție cu blocarea acestui obiect va fi respinsă.
- Dacă tranzacția impune o blocare S pe obiect, atunci
- O solicitare a unei alte tranzacții X-lock pe acest obiect va fi respinsă
- Se va accepta o cerere dintr-o altă tranzacție cu blocări S a acestui obiect
Este dovedit faptul că tranzacția serializabilă (sau, în caz contrar, izolația lor) este asigurată prin utilizarea unui protocol de blocare în două faze (2LP - Two-Phase Locks), conform căreia toate blocările efectuate de o tranzacție sunt eliminate numai atunci când este completă. Te satisface următoarea tranzacție este împărțit în două faze: (1) - acumulare de ecluze (2) - eliberarea broaștei ca rezultat al comiterii sau rulării înapoi.
Din nefericire, utilizarea mecanismului de blocare are ca rezultat o procesare mai lentă a tranzacțiilor, deoarece sistemul trebuie să aștepte până la eliberarea datelor capturate de tranzacția concurențială. Această problemă poate fi rezolvată prin reducerea fragmentelor de date captate de tranzacție. În funcție de obiectele capturate, există mai multe niveluri de blocare.- întreaga bază de date este blocată - în mod evident, această opțiune este inacceptabilă, deoarece reduce modul de operare multi-utilizator la un singur utilizator
- tabele separate sunt blocate
- paginile sunt blocate (pagina - un fragment al tabelului cu dimensiunea de obicei de 2-4 KB, o unitate de alocare a memoriei pentru prelucrarea datelor de către sistem)
- înregistrările sunt blocate
- câmpurile separate sunt blocate
Limba SQL oferă, de asemenea, o modalitate de a controla indirect viteza tranzacțiilor prin specificarea nivelului de izolare al tranzacției. Sub nivelul de izolare al unei tranzacții, se înțelege că poate apărea una dintre situațiile de eroare de mai sus. Standardul SQL definește 4 nivele de izolare: