Documente online.
Zona de administrare documente. Fisierele tale
Am uitat parola x Creaza cont nou
 HomeExploreaza
upload
Upload




Tranzactiile in J2EE

java


Tranzactiile īn J2EE

Unul dintre serviciile foarte valoroase puse la dispozitie de platforma J2EE īl reprezinta tranzactiile. Tranzactiile permit dezvoltarea unor aplicatii robuste, īn sensul ca permit operatiilor critice sa ruleze predictibil. Īn trecut, tranzactiile erau dificil de utilizat, deoarece programatorii trebuiau sa lucreze direct cu Transaction API. Īn cazul EJB, se beneficiaza de tranzactii fara a fi nevoie sa se scrie cod. Tranzactiile sunt īn miezul tehnologiei EJB, motiv pentru care sunt putin mai dificile.



2.6.1. Necesitatea tranzactiilor

Exista situatii cānd este preferabil sa se execute mai multe operatiuni distincte īmpreuna, adica fie sa se execute toate cu succes, fie nici una. Daca una dintre ele nu reuseste, atunci sa se revina la starea initiala īn care nici una dintre ele nu s-a executat. Un astfel de exemplu este transferul unei sume de bani dintr- un cont īn altul. Trebuie retr 737e47h ase fonduri dintr-un cont si depuse īn alt cont. Daca reusesc ambele operatiuni, totul este īn ordine, īnsa, daca, de exemplu, reuseste retragerea din primul cont si nu reuseste depunerea īn al doilea cont, este de dorit ca sa se renunte la ambele operatiuni. Cu alte cuvinte, se doreste ca cele doua operatiuni sa fie privite ca o singura operatiune atomica , adica indivizibila.

Desigur aceasta ar putea fi realizata prin prinderea exceptiilor la fiecare pas si, īn caz de exceptie, prin refacerea datelor cu cele initiale, ca īn urmatorul cod:

Cod īn care se realizeaza atomicitatea prin prinderea exceptiilor

trycatch(Exception ex)

trycatch(Exception ex)

Īnsa, īn aceasta abordare, exista mai multe probleme:

Trebuie luate īn calcul toate problemele posibile la fiecare pas si īn codul de tratare a exceptiei, trebuie refacute toate modificarile anterioare

Codul este greu de urmarit si de asemenea este foarte predispus la erori

Problema se complica foarte mult si este usor de scapat de sub control daca operatiunile sunt mai complicate si mai multe. De exemplu, īn cazul īn care se doreste tratarea a 10 pasi.

Problema se complica si mai mult daca luam īn calcul faptul ca operatiunile ar putea fi distribuite, adica daca mai multe masini care comunica īntre ele prin retea vor participa la realizarea operatiunilor (cum este cazul īn aplicatiile J2EE mai complexe). Īn acest caz, trebuie luat īn calcul si faptul ca reteaua poate sa cada īn decursul unei asemenea operatiuni. Ce se īntāmpla daca reteaua cade īn decursul unei operatii bancare distante? E drept ca de partea clientului (sa zicem o interfata pentru aplicatia bancara care ruleaza pe server), se va ridica o exceptie, dar aceasta va fi ambigua, deoarece nu se stie daca reteaua a cazut īnainte sau dupa ce s-a facut retragerea de bani din cont. Tot ce se observa este ca īn decursul celor doua operatii, care se petreceau distant, a aparut o cadere a retelei. Nu se va putea detecta īn nici un mod daca banii au fost sau nu retrasi din cont. Acest lucru este complet inacceptabil pentru orice aplicatie serioasa. Problema aceasta este rezolvabila prin tranzactii, deoarece ele pun la dispozitie un mecanism de refacere a datelor, daca apar astfel de erori.

Un alt caz, īn care tranzactiile sunt necesare, este cel īn care exista mai multe aplicatii care actioneaza simultan asupra acelorasi date. Sa presupunem ca este vorba tot despre un cont bancar asupra caruia actioneaza doua aplicatii din doua departamente diferite. Īn acest caz, este posibil ca o aplicatie sa modifice unele date, īn timp ce cealalta modifica alte date ce tin de acelasi cont bancar. Aceasta duce cu siguranta la date inconsistente, ceea ce este complet inacceptabil pentru un cont bancar. Tot tranzactiile sunt cele care raspund la problema accesului concurent al utilizatorilor asupra datelor. Ele vor garanta ca accesul concurent al mai multor utilizatori asupra acelorasi date nu va duce la coruperea datelor.

2.6.2. Definirea tranzactiilor si avantajelor lor

O tranzactie este un set de operatii care apare utilizatorului ca fiind executata sub forma unei operatiuni indivizibile (atomice). Īn acest fel, se elimina si problema caderilor retelei, care va lasa datele īntr-o forma consistenta indiferent de momentul īn care apare caderea retelei, deoarece se va reveni la starea initiala. Tranzactiile permit mai multor utilizatori sa utilizeze aceleasi date si garanteaza ca tot ceea ce un client modifica va fi complet modificat fara a aparea o īntretesere cu ceea ce modifica alt client.

Mai mult, cānd se utilizeaza tranzactii, operatiunile executate vor beneficia de patru avantaje garantate. Ele sunt: atomicitatea, consistenta, izolarea si durabilitatea.

Atomicitatea garanteaza ca operatiunile sunt legate unele de altele si vor fi executate sub forma unei singure operatiuni continue. Se garanteaza totul sau nimic: fie se executa toate operatiunile cu succes, fie nici una. Īn cadrul unei tranzactii, pot participa mai multe componente, tranzactia va reusi numai daca toate componentele nu īsi folosesc dreptul de veto, cu alte cuvinte numai daca toate operatiunile au fost realizate cu succes.

Consistenta garanteaza ca, dupa terminarea unei tranzactii, starea sistemului va fi una consistenta. De exemplu, pentru un cont bancar, s-ar putea impune regula ca īntotdeauna soldul sa fie pozitiv. Totusi, īn cadrul unei tranzactii, s-ar putea sa se faca īntāi o retragere si apoi o depunere. De moment s-ar putea ca soldul sa fie negativ (dupa retragere), deci contul sa fie īntr-o stare inconsistenta. Totusi dupa terminarea tranzactiei (dupa ce s-a reusit īn acest caz depunerea), starea contului va fi consistenta. Pentru cineva, care priveste din exterior, starea contului va fi tot timpul consistenta.

Izolarea protejeaza fiecare tranzactie de a vedea rezultatele partiale produse de o alta tranzactie, ce lucreaza asupra acelorasi date. Izolarea permite mai multor tranzactii sa scrie si citeasca simultan aceleasi date din baza de date, fara a sti una de cealtalta, deoarece ele sunt izolate unele de altele. Fiecare client vede baza de date ca si cum el ar fi singurul care opereaza asupra ei. Sistemul de tranzactii foloseste, la nivelul de jos, protocoale de sincronizare asupra bazei de date. Īn decursul unei tranzactii, se obtine, īn mod automat, blocarea unor date pentru o anumita tranzactie, dupa nevoie. Aceasta garanteaza ca nici o alta tranzactie nu va putea modifica acele date cāta vreme ele sunt blocate. Īn acest fel, se elimina problema īntreteserii actiunilor din tranzactii diferite asupra acelorasi date.

Durabilitatea garanteaza ca modificarile asupra bazelor de date vor supravietui caderilor de orice fel: masinii, retelei, etc. Pentru aceasta se mentine o istorie a tranzactiilor, care poate fi folosita pentru refacere. Daca apare cumva o cadere, datele pot fi reconstruite prin parcurgerea pasilor īnregistrati īn istorie.

2.6.3. Modelul de tranzactii suportat de J2EE: flat transactions

Exista mai multe feluri de a realiza tranzactiile, iar aceste feluri sunt denumite modele de tranzactii. Cele mai populare sunt flat tranzactions si nested tranzactions. Singurul model de tranzactii suportat īn prezent de J2EE este flat transactions.

O flat transaction este o serie de operatii executate ca un tot. O tranzactie careia īi reusesc toti pasii este declarata committed (comisa), īn vreme ce o tranzactie careia unul dintre pasi nu i-a reusit este declarata aborted (renuntata). Atunci cānd o tranzactie este declarata committed, toate operatiunile care afecteaza date persistente devin permanente. Daca o tranzactie este declarata aborted, atunci nici una dintre operatiuni nu devine permanenta, ci starea este derulata invers (rolled back). O tranzactie de tipul flat transaction asigura totul sau nimic. Īn cele ce urmeaza, se va explica cum se realizeaza derularea inversa a unei tranzactii, daca aceasta este declarata aborted.

Se ia īn considerare o flat transaction care include operatii asupra unor baze de date. Dupa ce tranzactia īncepe, una dintre componentele de business obtine o conexiune la o baza de date. Aceasta conexiune este automat adaugata īn tranzactia īn care participa respectiva componenta. Apoi componenta realizeaza unele operatiuni ce implica persistenta, ca de exemplu un update īn baza de date. Toate aceste operatiuni asupra bazei de date nu sunt aplicate permanent asupra datelor de catre resourse manager-ul ei, numai cānd primeste comanda commit. Aceasta comanda este, īnsa, trimisa spre baza de date numai cānd tranzactia a reusit. Daca tranzactia nu a reusit si este declarata aborted, atunci nu se va trimite bazei de date comanda commit, motiv pentru care modificarile nu vor deveni niciodata permanente, ci vor fi complet neglijate.

Cel mai important lucru care trebuie retinut este ca, īn mod tipic, componentele de business nu vor contine nici un fel de logica pentru a trata cazul īn care se renunta la tranzactie (cu alte cuvinte nu vor contine logica de undo). Aceasta este realizata de sistem īn spatele scenelor, bineīnteles īn colaborare cu baza de date. Rolul componentelor este de a controla tranzactiile si de a le declara aborted; derularea īnapoi este realizata īn mod automat de sistem. Din perspectiva programatorului, fiecare componenta trebuie sa īsi realizeze operatiunile legate de persistenta, ca si cānd tranzactia ar reusi.

2.6.4. Tranzactii declarative si programatice

Īn EJB, codul componentelor nu este niciodata utilizat de sistemul de tranzactii de la nivelul de jos, īn sensul ca nu vor exista niciodata interactiuni cu vreun transaction manager sau resource manager. Codul aplicatiilor este scris la un nivel mai īnalt, fara a fi nevoie sa se ia īn considerare sistemul de tranzactii efectiv utilizat. Sistemul de tranzactii este abstractizat īn totalitate de containerul EJB, care ruleaza īn spatele scenelor. Componentele trebuie doar sa specifice daca sunt de acord ca tranzactia sa fie declarata committed, iar, daca ele nu sunt de acord, tranzactia este declarata aborted.

Tranzactiile se deruleaza īn spatele scenelor, īnsa trebuie specificata frontiera lor: cine īncepe o tranzactie si cine declara o tranzactie committed sau aborted? Demarcarea frontierelor unei tranzactii se poate face declarativ sau programatic.


Īn cazul demarcarii programatice a tranzactiilor, se va specifica īn codul componentelor EJB cānd īncepe o tranzactie, cānd este ea declarata commited sau aborted. Majoritatea sistemelor lucreaza īn acest fel. De exemplu, īn cadrul unei aplicatii bancare, s-ar putea sa existe o componenta care, printre altele, va avea o metoda ce realizeaza transferul de bani dintr-un cont īn altul. Īn cadrul acestei metode, īnainte de a se realiza prima operatiune, se va īncepe din cod o tranzactie, apoi se vor realiza operatiunile necesare transferului si apoi se va declara tranzactia drept committed. Daca, īnsa, apare vreo exceptie, tranzactia se va declara aborted.

Figura 2.25. Un bean cu tranzactii declarative

Pentru cazul demarcarii declarative a tranzactiilor, sarcina de a īncepe o tranzactie si de a o declara committed sau aborted, cade asupra containerului. Componentele vor fi adaugate īn mod automat īntr-o tranzactie. Studiind acelasi exemplu de bean, care reprezinta un cont bancar, el va avea, si īn acest caz, o metoda de transfer de numerar dintr-un cont īn altul. Cānd un client apeleaza metoda de transfer bancar, containerul EJB va intercepta cererea si va īncepe o noua tranzactie īn mod automat. Apoi containerul va apela metoda bean - ului, care va realiza operatiile din cadrul acelei tranzactii. Īn cadrul metodei, poate fi realizat orice: executarea de logica, scrierea īn baze de date, apelarea altor bean - uri. Daca apare vreo problema, bean - ul va semnaliza containerul ca tranzactia trebuie declarata aborted. Containerul va apela apoi sistemul de tranzactii, ca īn cazul bean - ului TellerBean din Figura 2.25.

Tranzactiile declarative reprezinta o facilitate importanta, deoarece bean - urile nu trebuie sa mai apeleze nici un API de tranzactii. De fapt, bean - urile si clientul nici macar nu stiu ca participa īn tranzactii, deoarece se vor petrece īn spatele scenelor.

Alegerea īntre tranzactii declarative si programatice este la latitudinea programatorului componentelor. Īn cadrul unei aplicatii, este de preferat utilizarea tranzactiilor declarative, fiindca pentru tranzactiile programatice va trebui sa se utilizeze Java Transaction API (JTA). Totusi containerul trebuie sa afle ce tip de tranzactii sunt aplicate unui bean. Pentru aceasta este folosit un transaction attribute, care este o setare specificata īn deployment descriptor. Fiecare bean are un descriptor pentru deployment, īn care sunt continute o serie de proprietati pe care le va folosi containerul EJB pentru a interactiona cu bean - ul.

Containerul EJB va sti cum sa abordeze tranzactiile din atributele continute īn deployment descriptor. Se pot specifica atribute pentru deployment care sa fie valabile pentru un īntreg bean si se pot specifica atribute pentru fiecare metoda a bean - ului. Daca se specifica atribute pentru o metoda, atunci acel atribut este prioritar fata de atributul specificat pentru īntregul bean. Cu alte cuvinte, atributul specificat pentru īntregul bean se va aplica numai metodelor care nu au un atribut al lor. Modul de specificare a atributelor privitoare la tranzactii poate fi observat din Figura 2.26.

2.6.5. Valorile atributelor privitoarea la tranzactii

Īn exemplul din Figura 2.26., este prezentata modalitatea de specificare a atributelor privitoare la tranzactii pentru un entity bean denumit TheSecurity. Se observa ca, īn cadrul atributelor privitoare la tranzactii, s-a specificat container managed transactions, cu alte cuvinte tranzactiile vor fi delimitate de catre container. Pentru metoda getAllTasks(), se specifica un atribut pentru tranzactii.

Valorile posibile ale atributului legat de tranzactii pentru orice metoda sunt cele din combo box si vor fi explicate īn continuare.

Valoarea not supported pentru atributul legat de tranzactii semnifica faptul ca metoda respectiva nu poate fi implicata īn tranzactii, deoarece nu le suporta. Sa presupunem ca bean - ul A īncepe o tranzactie si apoi apeleza o metoda de-a altui bean B, care nu suporta tranzactii. Tranzactia īnceputa de A este suspendata pāna ce se termina metoda din B, apoi este reluata.

Acest atribut ar trebui utilizat atunci cānd se stie ca nu este nevoie de avantajele pe care le ofera tranzactiile (atomicitate, consistenta, izolare, durabilitate), cānd, de exemplu, metoda bean - ului nu realizaza operatii critice. De exemplu, o metoda care returneaza, orientativ, numarul de utilzatori ce au vizitat un magazin virtual nu este critica, spre deosebire de cea care va face transferul de bani din contul clientului īn cel al magazinului.

Figura 2.26. Specificarea unui atributului privitor la tranzactii cu Deployment Tool din implementarea de referinta J2EE de la Sun

Valoarea required pentru atributul legat de tranzactii semnifica nevoia ca īntotdeauna acea metoda sa participe īntr-o tranzactie. Daca, deja, exista o tranzactie care se deruleaza, atunci apelul metodei bean - ului este adaugat īn acea tranzactie, altfel se va īncepe una noua.

Valoarea requires new semnifica faptul ca, īntotdeauna la apelul acelei metode, se va īncepe o noua tranzactie, indiferent ca este deja una pe rol sau nu. Daca, deja, exista o tranzactie īn derulare, ea va fi suspendata pe parcursul derularii noii tranzactii. Cānd noua tranzactie s-a terminat (cu succes sau nu), se va relua prima tranzactie. Aceast atribut trebuie sa fie utilizat atunci cānd este nevoie ca o suita de operatiuni sa fie executate ca un tot unitar, fara a permite nici unei alte parti de program sa influenteze executia acelui tot.

Valoarea supports este foarte asemanatoare cu required, cu exceptia faptului ca, daca nu este o tranzactie pe rol de care sa se lipeasca, atunci nu va īncepe una noua.

Valoarea mandatory semnifica faptul ca este neaparat nevoie ca sa fie deja o tranzactie pe rol īn momentul īn care se apeleaza metoda bean - ului. Daca nu exista vreo tranzactie īn derulare, atunci se va arunca exceptia javax.ejb.TransactionRequired. Containerul nu va īncepe o noua tranzactie daca nu era una deja īn derulare.

Valoarea never semnifica faptul ca niciodata acea metoda nu va participa īntr-o tranzactie. Daca, īn momentul cānd este apelata metoda exista o tranzactie īn derulare, se va arunca o exceptie.


Document Info


Accesari: 2188
Apreciat: hand-up

Comenteaza documentul:

Nu esti inregistrat
Trebuie sa fii utilizator inregistrat pentru a putea comenta


Creaza cont nou

A fost util?

Daca documentul a fost util si crezi ca merita
sa adaugi un link catre el la tine in site


in pagina web a site-ului tau.




eCoduri.com - coduri postale, contabile, CAEN sau bancare

Politica de confidentialitate | Termenii si conditii de utilizare




Copyright © Contact (SCRIGROUP Int. 2024 )