Lucrul cu bd în c # 4

4.3.5. tranzacții

O tranzacție este executarea unei secvențe de comenzi (constructe SQL) în bază de date, care este fie fixă ​​atunci când fiecare comandă este implementată cu succes, fie este anulată dacă cel puțin o comandă eșuează. Majoritatea sistemelor DBMS moderne acceptă un mecanism de tranzacție, iar marea majoritate a aplicațiilor client care le utilizează utilizează tranzacțiile pentru a executa comenzile lor.







Se pune întrebarea - de ce avem nevoie de tranzacții? Să presupunem că baza de date BDTur_firm2 necesită inserarea înregistrărilor legate în două tabele - "Turiști" și "Informații despre turiști". În cazul în care urmează să fie introduse în „turiști“ de masă recordul va fi greșit, de exemplu, din cauza codului turistic specificat greșit, baza de date nu permite să facă o schimbare, dar în „Informații despre apare intrare de tabel inutile turiștilor. Luați în considerare această situație cu un exemplu.

Run Management Studio, în noua formă introducem o interogare pentru a adăuga două intrări:

Două înregistrări sunt adăugate cu succes în baza de date:

(1 rânduri afectate) // sau (linii prelucrate: 1)
(1 rânduri afectate) // sau (linii prelucrate: 1)

Acum vom provoca o greșeală - vom schimba codul de turism doar în a doua solicitare:

Apare un mesaj că prima înregistrare nu poate fi inserată cu valoarea câmpului cheie deja disponibilă. A doua intrare, cu toate acestea, se adaugă la tabel:

Mesajul 2627, nivelul 14, starea 1, linia 1
Încălcarea constrângerii PRIMARY KEY "PK_Tourists". Nu se poate introduce cheia duplicat în obiectul 'dbo.Tourists'.
Declarația a fost anulată.
(linii prelucrate: 1)

Să extragem conținutul ambelor tabele cu următoarea interogare dublă:

SELECT * FROM Tourists
SELECT * FROM [Informații turistice]

În tabelul "Informații despre turiști", ultima intrare a fost adăugată fără nicio legătură cu înregistrarea tabelului "Turiști" (Figura 99). Pentru a evita astfel de erori, trebuie să aplicați tranzacția.

Lucrul cu bd în c # 4

Fig. 99. Conținutul tabelelor "Turiști" și "Informații despre turiști" - încălcarea comunicării

Ștergem toate intrările din ambele tabele și construcțiile SQL inițiale sub forma unei tranzacții:

Tranzacția este declarată utilizând comanda BEGIN TRAN. Apoi, sunt creați doi parametri: @OshibkiTabliciTourists, OshibkiTabliciInfoTourists pentru colectarea erorilor. După prima solicitare, returnez valoarea pe care o atribuie funcția încorporată @@ ERROR la ​​primul parametru:

Același lucru se face și după a doua interogare pentru un alt parametru:

Verificăm valorile ambilor parametri, care trebuie să fie egali cu zero în absența erorilor:

Dacă @ OshibkiTabliciTourists = 0 și @ OshibkiTabliciInfoTourists = 0

În acest caz, confirmăm tranzacția (în acest caz, efectuând modificări) cu comanda COMMIT TRAN. În caz contrar - în cazul în care cel puțin unul dintre parametrii @OshibkiTabliciTourists @OshibkiTabliciInfoTourists și este diferit de zero, a anula tranzacția utilizând comanda ROLLBACK TRAN.

După finalizarea tranzacției, primiți un mesaj despre adăugarea a două rânduri:

(linii prelucrate: 1)
(linii prelucrate: 1)

Din nou, modificați codul de destinație turistică în a doua solicitare:

Începem tranzacția - același mesaj apare exact ca în cazul cererilor obișnuite:

Mesajul 2627, nivelul 14, starea 1, linia 3
Încălcarea constrângerii PRIMARY KEY "PK_Tourists". Nu se poate introduce cheia duplicat în obiectul 'dbo.Tourists'.
Declarația a fost anulată. (linii prelucrate: 1)

Cu toate acestea, acum nu s-au făcut modificări la al doilea tabel (Figura 100).

Lucrul cu bd în c # 4

Fig. 100. Conținutul tabelelor "Turiști" și "Informații despre turiști" după efectuarea unei tranzacții nereușite

Un mesaj (1 rând afectat) indicând "adăugarea" unei înregistrări, în acest caz înseamnă doar că cel de-al doilea proiect SQL a fost corect, iar înregistrarea ar putea fi adăugată dacă tranzacția a avut succes.







Astfel, mecanismul de tranzacție menține integritatea datelor din cele două tabele, nepermițându-l să fie rupt prin adăugarea de date incorecte.

Acum, să ne uităm la tranzacțiile din ADO .NET. Creați o nouă aplicație de consolă Easy Transaction. Vom stabili sarcina: să transferăm aceleași date în două tabele - "Turiști" și "Informații despre turiști".

Lista completă a acestei aplicații este după cum urmează:

Înainte de a începe aplicarea, ștergem din nou toate intrările din tabele. Dacă se realizează interogarea, apare un mesaj corespunzător și se adaugă înregistrări în tabel (Figura 101).

Lucrul cu bd în c # 4

Fig. 101. Aplicația EasyTransaction. Tranzacția a fost finalizată

Repornirea acestei aplicații duce la respingerea tranzacției - nu puteți introduce înregistrări cu aceleași valori ale cheilor primare (Figura 102).

Lucrul cu bd în c # 4

Fig. 102. Aplicația EasyTransaction. Tranzacția a fost refuzată

Sub forma unei tranzacții, puteți executa executarea uneia sau mai multor proceduri stocate - de fapt, construcția generală are următoarea formă:

// Creați o conexiune
. consultați exemplul aplicației EasyTransaction
// Creați o tranzacție
myCommand.Transaction = conn.BeginTransaction ();
încerca <
// Executați comenzi, apelați una sau mai multe proceduri memorate
// Confirmați tranzacția
myCommand.Transaction.Commit ();
>
captura (Excepție ex) <
// Denegeți tranzacția
myCommand.Transaction.Rollback ();
>
în cele din urmă <
// Închideți conexiunea
conn.Close ();
>

Atunci când execută tranzacții de mai mulți utilizatori din aceeași bază de date, pot apărea următoarele probleme:

1. Citirea murdară - citirea "murdară". Primul utilizator inițiază o tranzacție care modifică datele. În acest moment, un alt utilizator (sau tranzacția pe care o creează) recuperează date parțial modificate care nu sunt corecte.

2. Citiri non-repetabile - citiri non-repetabile. Primul utilizator inițiază o tranzacție care modifică datele. În acest moment, un alt utilizator începe și termină o altă tranzacție. Primul utilizator care a citit repetat datele (de exemplu, dacă tranzacția sa include mai multe instrucțiuni SELECT) obține un set diferit de înregistrări.

3. Phantom citește - citește fantome. Primul utilizator pornește o tranzacție care selectează datele din tabel. În acest moment, un alt utilizator pornește și încheie tranzacția care introduce sau șterge înregistrările. Primul utilizator va primi un alt set de date care conține fantome - rânduri șterse sau modificate.

Pentru a rezolva aceste probleme, se dezvoltă patru niveluri de izolare a tranzacțiilor:

1. Citiți necondiționat. Tranzacția poate citi datele cu care funcționează alte tranzacții. Aplicarea acestui nivel de izolare poate duce la toate problemele enumerate.

2. Citește angajamentul. Tranzacția nu poate citi datele cu care se confruntă alte tranzacții. Utilizarea acestui nivel de izolare elimină problema citirii "murdare".

3. Citiți repetabil. Tranzacția nu poate citi datele cu care se confruntă alte tranzacții. De asemenea, alte tranzacții nu pot citi datele cu care lucrează această tranzacție. Utilizarea acestui nivel de izolare elimină toate problemele, cu excepția fantomelor de citire.

4. Serializabil. Tranzacția este complet izolată de alte tranzacții. Utilizarea acestui nivel de izolare elimină complet toate problemele.

Lucrul cu bd în c # 4

Folosind cel mai înalt nivel de izolare (Serializable) înseamnă o maximă siguranță și, în același timp, cea mai mică performanță - toate tranzacțiile sunt efectuate într-o serie de ulterior forțată să aștepte finalizarea celui precedent. În schimb, aplicarea celui mai scăzut nivel (Citiți neangajat) înseamnă performanță maximă și nesiguranță totală. Cu toate acestea, nu se pot oferi recomandări universale cu privire la aplicarea acestor niveluri - în fiecare situație specifică, soluția va depinde de structura bazei de date și de natura interogărilor efectuate.

Pentru a seta nivelul de izolare, utilizați următoarea comandă:

SET NIVELUL DE IZOLARE A TRANZACȚIILOR
CITIȚI NECOMMITAT
sau CITIȚI ÎNCHEIAT
sau citire REPEATABILĂ
sau SERIALIZABILE

De exemplu, într-o tranzacție care adaugă două intrări, nivelul de izolare este indicat după cum urmează:

ÎNCETAREA SETĂRII NIVELULUI DE IZOLARE TRAN SERIALIZABIL
DECLARE @OshibkiTabliciTourists int, @OshibkiTabliciInfoTourists int
.
ROLLBACK TRAN

În ADO .NET, nivelul de izolare poate fi setat la crearea tranzacției:

myCommand.Transaction = conn.BeginTransaction (System.Data.IsolationLevel.Serializable); În plus, sunt suportate încă două nivele (Figura 104):

1. Haosul. Tranzacția nu poate suprascrie alte tranzacții neacceptate cu un nivel de izolare mai mare, dar poate suprascrie modificările efectuate fără a utiliza tranzacțiile. Datele cu care se execută tranzacția curentă nu sunt blocate;

2. Nespecificat. Un nivel separat de izolare care poate fi aplicat, dar care nu poate fi determinat. Tranzacția cu acest nivel poate fi utilizată pentru a vă stabili nivelul de izolare.

Lucrul cu bd în c # 4

Fig. 104. Stabilirea nivelului unei tranzacții

Tranzacțiile asigură integritatea bazei de date, atunci când dezvoltă aplicații pe mai multe niveluri, aplicarea lor este o regulă obligatorie.







Articole similare

Trimiteți-le prietenilor: