Cum de a lucra de fapt @transactional blog-ul de primăvară Anatoli Korsakov

În acest articol, vom coborî în labirintul de tranzacții de gestionare a cadrului de primăvară. Ne vom uita la modul de a construi sub „capota“ de lucru adnotări @Transactional.

JPA și gestionarea tranzacției

Este important de remarcat faptul că specificația APP în sine nu oferă nici o tranzacție de gestionare declarativă. Atunci când se utilizează APP este DI software-ul tranzacție container (Injection Dependență), controlată de dezvoltator:

O astfel de metodă de control pentru tranzacția dă codul de transparență, dar există câteva dezavantaje:

  • O mulțime de cod repetitiv și o tendință de un comportament eronat
  • Orice greșeală este un impact foarte mare
  • Erori de dificile pentru a depana și de redare
  • Se complică codul lizibilitate
  • Ce ar trebui să fac în cazul în care metoda solicită o altă metodă de a tranzacțiilor?

Noi folosim adnotare de primăvară @Transactional

C adnotare @Transactional, un exemplu poate fi simplificată după cum urmează:

Acest cod este mult mai convenabil și lizibil, iar în momentul în care se recomandă utilizarea acestei abordări pentru managementul tranzacție în primăvară.

Folosind @Transactional, multe aspecte importante ale modului în care tranzacția fiind răspândit (propagare) sunt prelucrate automat. În acest caz, dacă o altă metodă este invocată cu metoda de tranzacție businessLogic (), această metodă se face să se alăture unei tranzacții.

Un dezavantaj încă acolo: este greu de înțeles cum funcționează din interior, acest mecanism puternic și greu de depanare atunci când apare o eroare.

Ce înseamnă @Transactional?

Unul dintre cunoștințele cheie despre @Transactional este că există două concepte separate pentru examinare, fiecare dintre acestea are propria sa zonă a ciclului de acțiune și de viață:

  • context, persistența
  • tranzacție de baze de date

Rezumat în sine definește domeniul de aplicare al unei singure tranzacții de baze de date. DB tranzacție are loc în contextul acțiunii persistență.

Contextul Persistența este în JPA EntityManager, în cadrul clasei care utilizează sesiune ORM-cadru Hibernate (atunci când este utilizat ca furnizor de persistență Hibernate).

Contextul Persistența este un obiect-sinhronayzer, care urmărește starea unui set limitat de obiecte Java și sincronizează modificările în starea acestor facilități cu starea înregistrărilor corespunzătoare în baza de date.

O entitate obiect Managerul nu corespunde întotdeauna aceeași tranzacție de bază de date. O entitate obiect Manager poate fi folosit baza de date cu mai multe tranzacții.

Când EntityManager se referă la baza de date cu mai multe tranzacții?

Cel mai frecvent caz apare atunci când o aplicație utilizează un șablon «Deschideți Session în Vizualizare» pentru a preveni excluderea initializare „leneș“.

În acest caz, interogările care ar putea fi efectuate de către o singură tranzacție printr-un apel de la stratul de serviciu, se efectuează în tranzacții separate într-un strat de vedere, dar ele sunt realizate prin același administrator Entitate.

Un alt caz este atunci când un context marcat de persistenta dezvoltator ca PersistenceContextType.EXTENDED, ceea ce înseamnă că aplicația utilizează antipattern „o sesiune la cererea.“

Aceasta definește relația dintre tranzacție și EntityManager?

Desigur, fiecare dezvoltator decide pentru sine, dar alegerea cea mai comună este de a utiliza APP Entitate Managerul cu strategia de „aplicare Manager de o entitate pe o singură tranzacție.“ Codul de mai jos demonstrează modul de implementare Manager Entitatea Bean:

În acest exemplu, implicit modul de operare „O aplicație Manager de entitate pe o singură tranzacție.“ În acest mod, dacă vom folosi Managerul Entitate într-o adnotare marcat metoda @Transactional, atunci această metodă va fi efectuată într-o singură tranzacție de bază de date.

Cum @PersistenceContext?

O întrebare vine în minte, cum se poate pune în aplicare @PersistenceContext managerul entității o dată la începutul containerului, având în vedere că durata de viață a managerilor entității sunt puține și, de obicei, au nevoie de mai mult pentru o singură cerere?

Răspunsul este: nu se poate. Entitate Manager este interfața, iar apoi este introdus în recipientul nu este, în sine, manager de entitate este contextul proxy conștient, care va fi delegată unui anumit manager de entitate în timpul rulării.

De obicei, această clasă particulară este folosită pentru SharedEntityManagerInvocationHandler proxy, care poate fi determinată prin utilizarea debugger.

Cum, atunci, funcționează @Transactional?

context, persistența Proxy imlementiruet EntityManager nu este un set suficient de componente pentru punerea în aplicare a declarativă de management de tranzacții. De fapt, ai nevoie de trei componente:

  • Proxy Entitate Managerul
  • aspect al tranzacției
  • Managerul de tranzacții

Să ne uităm la fiecare și a vedea interacțiunile lor.

aspect al tranzacției

Aspectul unei tranzacții - «în jurul» aspect, care se numește înainte și după activitatea metodei adnotat. O clasă specifică pentru punerea în aplicare a acestui aspect al acestei TransactionInterceptor.

Aspect al tranzacției are două funcții principale:

  • La momentul de timp „înainte de“ aspect determină dacă pentru a efectua o metodă realizată în cadrul bazei de date de tranzacție deja suschestuvuyuschey sau o nouă tranzacție separată ar trebui să înceapă.
  • La momentul „după“ aspect decide ce să facă cu tranzacția comite, revocați sau lăsați neacoperit.

La momentul „înainte de“ aspectul în sine nu conține nici o logică a deciziei, decizia de a începe o nouă tranzacție, dacă este necesar, administratorul delegat Transaction.

Managerul de tranzacții

tranzacții poate oferi manager de mare trebuie să răspundă la două întrebări:

  • Fie pentru a crea un nou manager entitate?
  • În cazul în care o nouă tranzacție de bază de date dacă să înceapă?

Răspunsurile sunt necesare pentru a furniza, la momentul când tranzacția se numește aspecte ale logicii, la momentul „înainte“. Managerul de tranzacții face o decizie pe baza următoarelor fapte:

  • efectuate în cazul în care cel puțin o tranzacție în momentul actual nu mai există
  • atributul «propagarea» într-o metodă adnotată @Transactional (de exemplu, REQUIRES_NEW începe întotdeauna o nouă tranzacție).

În cazul în care managerul a decis să creeze o nouă tranzacție, atunci:

  • Un nou manager entitate
  • „Legarea» managerul entității la firul de curent (fir)
  • „Capture“ dintr-un compus dintr-un bazin de conexiuni de baze de date
  • „Legarea“ conexiunii la fluxul de curent

Și managerul entității și compusul legat la firul de curent, folosind un variabile ThreadLocal.

Acestea sunt stocate în fluxul până când tranzacția este finalizată, iar apoi transmis managerul de tranzacție pentru curățare, deoarece acestea nu vor mai fi necesare.

Orice parte a programului, care are nevoie de managerul entității curent sau compusul le poate obține din fluxul. Această componentă a programului, ceea ce face acest lucru este entitatea proxy manager.

EntityManager proxy

Proxy Entitate Managerul (care a fost introdus mai devreme) este ultima piesă de puzzle pe porțiuni. Atunci când o metodă de afaceri de a face un apel, de exemplu, entityManager.persist (). apelul nu este invocat în mod direct de la managerul entității.

În schimb, metoda de afaceri apelează proxy, care devine managerul entității curente din fluxul, în care a pus managerul de tranzacție.

Știind acum tot mecanismul @Transactional parte, să treacă prin configurația de primăvară de obicei trebuie să-l opereze toate.

Punerea în practică a întregului puzzle împreună

Să ne descrie configurația celor trei componente necesare pentru funcționarea corespunzătoare adnotări @Transactional. Începem prin a defini Entitate Factory Manager.

Acest lucru va permite proxy manager Entitate să injecteze prin @PersistenceContext adnotare:

Pre Urmatorul pas va configura managerul de tranzacție și să aplice aspecte ale tranzacțiilor la cursuri adnotat @Transactional:

Rezumat de primăvară @EnableTransactionManagement indică faptul că clasele adnotate cu @Transactional, ar trebui să fie înfășurată aspect tranzacțional. Acum puteți utiliza adnotare @Transactional.

concluzie

tranzacții mecanism de control declarativă prezentat de primăvară-cadru, desigur puternic, dar poate fi utilizat incorect, și poate fi ușor confundat cu configurație.

Înțelegerea modului în care funcționează este foarte util pentru rezolvarea problemelor în cazul în care mecanismul nu funcționează conform așteptărilor.

Cel mai important lucru pentru a păstra mereu în minte este că există două concepte care trebuie luate în considerare: contextul tranzacției de baze de date și persistență, fiecare cu propriul său ciclu de viață non-evidente.

(Vizitat de 3457 de ori, 28 de vizite de azi)

Trimite acest link: