Programmēšana

Izplatītie darījumi pavasarī ar XA un bez tā

Lai gan izplatītajiem darījumiem pavasarī parasti tiek izmantots Java Transaction API un XA protokols, jums ir citas iespējas. Optimālā ieviešana ir atkarīga no jūsu lietojumprogrammas izmantoto resursu veidiem un kompromisiem, kurus vēlaties veikt starp veiktspēju, drošību, uzticamību un datu integritāti. Šajā JavaWorld funkcijā SpringSource Deivids Sijers iepazīstina jūs ar septiņiem izplatīto darījumu modeļiem pavasara lietojumprogrammās, trīs no tiem ar XA un četri bez. Līmenis: Starpnieks

Spring Framework atbalsts Java Transaction API (JTA) ļauj lietojumprogrammām izmantot sadalītos darījumus un XA protokolu, nedarbojoties Java EE konteinerā. Tomēr pat ar šo atbalstu XA ir dārga, un tā administrēšana var būt neuzticama vai apgrūtinoša. Tad var sagaidīt pārsteigumu, ka noteikta lietojumprogrammu klase var pilnībā izvairīties no XA izmantošanas.

Lai palīdzētu jums saprast apsvērumus, kas saistīti ar dažādām pieejām izplatītajiem darījumiem, es analizēšu septiņus darījumu apstrādes modeļus, nodrošinot kodu paraugus, lai tie būtu konkrēti. Es parādīšu modeļus apgrieztā drošības vai uzticamības secībā, sākot ar tiem, kuriem visaugstākajos apstākļos ir visaugstākā datu integritātes un atoma garantija. Pārejot uz leju sarakstā, tiks piemēroti vairāk brīdinājumu un ierobežojumu. Arī modeļi ir aptuveni apgrieztā izpildlaika secībā (sākot ar visdārgāko). Visi modeļi ir arhitektoniski vai tehniski, atšķirībā no biznesa modeļiem, tāpēc es nekoncentrējos uz uzņēmējdarbības lietām, tikai uz minimālo koda daudzumu, lai redzētu, kā katrs modelis darbojas.

Ņemiet vērā, ka tikai pirmie trīs modeļi ir saistīti ar XA, un tie var nebūt pieejami vai pieņemami veiktspējas dēļ. Es neapspriedu XA modeļus tik plaši kā pārējos, jo tie ir aplūkoti citur, lai gan es sniedzu vienkāršu pirmā paraugu. Izlasot šo rakstu, jūs uzzināsiet, ko jūs varat un ko nevar darīt ar izplatītiem darījumiem un kā un kad izvairīties no XA izmantošanas - un kad nē.

Sadalīti darījumi un atoms

A izplatīts darījums ir tāds, kas ietver vairāk nekā vienu darījumu resursu. Darījumu resursu piemēri ir savienotāji saziņai ar relāciju datu bāzēm un ziņojumapmaiņas starpprogrammatūra. Bieži vien šādam resursam ir API, kas izskatās kaut kas līdzīgs sākt (), atcelšana (), apņemties (). Java pasaulē darījumu resurss parasti tiek parādīts kā rūpnīcas produkts, ko nodrošina pamata platforma: datu bāzei tas ir Savienojums (Režisors Datu avots) vai Java noturības API (JPA) EntityManager; Java ziņu pakalpojumam (JMS) tas ir Sesija.

Tipiskā piemērā JMS ziņojums izraisa datu bāzes atjaunināšanu. Laika skalā sadalīta veiksmīga mijiedarbība notiek apmēram šādi:

  1. Sāciet ziņojumapmaiņas darījumu
  2. Saņemt ziņojumu
  3. Sākt datu bāzes darījumu
  4. Atjaunināt datu bāzi
  5. Izpildiet datubāzes darījumu
  6. Izpildiet ziņojumapmaiņas darījumu

Ja atjauninājumā radās datu bāzes kļūda, piemēram, ierobežojuma pārkāpums, vēlamā secība izskatīsies šādi:

  1. Sāciet ziņojumapmaiņas darījumu
  2. Saņemt ziņojumu
  3. Sākt datu bāzes darījumu
  4. Atjaunināt datu bāzi, neizdoties!
  5. Atgriezt datu bāzes darījumu
  6. Atgrieziet ziņojumapmaiņas darījumu

Šajā gadījumā ziņojums atgriežas starpprogrammatūrā pēc pēdējās atcelšanas un kādā brīdī atgriežas, lai saņemtu citā darījumā. Parasti tā ir laba lieta, jo pretējā gadījumā jums, iespējams, nav ierakstu par kļūmi. (Mehānismi automātiskas atkārtotas mēģināšanas un izņēmumu apstrādei ir ārpus šī raksta darbības jomas.)

Abu laika grafiku svarīga iezīme ir tā, ka tie ir atomu, veidojot vienu loģisku darījumu, kas vai nu pilnībā izdodas, vai arī pilnībā neizdodas.

Bet kas garantē, ka laika skala izskatās kā viena no šīm secībām? Jānotiek zināmai sinhronizācijai starp darījumu resursiem, tā ka, ja kāds apņemas, viņi abi to dara, un otrādi. Pretējā gadījumā viss darījums nav atoms. Darījums tiek sadalīts, jo ir iesaistīti vairāki resursi, un bez sinhronizācijas tas nebūs atoms. Sadalīto darījumu tehniskās un konceptuālās grūtības ir saistītas ar resursu sinhronizāciju (vai tā trūkumu).

Pirmie trīs modeļi, kas aplūkoti turpmāk, ir balstīti uz XA protokolu. Tā kā šie modeļi ir plaši atspoguļoti, es šeit par tiem sīkāk neiedziļināšos. Tie, kas pārzina XA modeļus, var vēlēties pāriet uz koplietojamo darījumu resursu modeli.

Pilna XA ar 2PC

Ja jums ir nepieciešamas gandrīz nepārliecinošas garantijas, ka jūsu lietojumprogrammas darījumi tiks atjaunoti pēc pārtraukuma, ieskaitot servera avāriju, Full XA ir jūsu vienīgā izvēle. Kopīgais resurss, kas šajā gadījumā tiek izmantots, lai sinhronizētu darījumu, ir īpašs darījumu pārvaldnieks, kas koordinē informāciju par procesu, izmantojot XA protokolu. Java, no izstrādātāja viedokļa, protokols tiek atklāts, izmantojot JTA Lietotāja darījums.

Tā kā XA ir sistēmas saskarne, tā ir tehnoloģija, kuru lielākā daļa izstrādātāju nekad neredz. Viņiem jāzina, ka tas ir tur, ko tas ļauj, ko tas maksā, un sekas tam, kā viņi izmanto darījumu resursus. Izmaksas rodas no divfāžu protokola (2PC) protokola, kuru darījumu pārvaldnieks izmanto, lai nodrošinātu, ka visi resursi vienojas par darījuma iznākumu pirms tā beigām.

Ja lietojumprogramma ir iespējota pavasarī, tā izmanto pavasari JtaTransactionManager un pavasara deklaratīvā darījumu pārvaldība, lai paslēptu informāciju par pamatā esošo sinhronizāciju. Izstrādātāja atšķirība starp XA un XA neizmantošanu ir rūpnīcas resursu konfigurēšana: Datu avots lietojumprogrammas un darījumu pārvaldnieks. Šajā rakstā ir iekļauts pieteikuma paraugs atomikos-db projekts), kas ilustrē šo konfigurāciju. The Datu avots gadījumi un darījumu pārvaldnieks ir vienīgie XA vai JTA specifiskie lietojumprogrammas elementi.

Lai redzētu, kā paraugs darbojas, veiciet vienības testus sadaļā com.springsource.open.db. Vienkāršs MulipleDataSourceTests klase vienkārši ievieto datus divos datu avotos un pēc tam izmanto pavasara integrācijas atbalsta funkcijas, lai atceltu darījumu, kā parādīts 1. sarakstā:

Saraksts 1. Darījuma atcelšana

@Transactional @Test public void testInsertIntoTwoDataSources () izmet izņēmumu {int count = getJdbcTemplate (). Update ("INSERT into T_FOOS (id, name, foo_date) values ​​(?,?, Null)", 0, "foo"); assertEquals (1, skaits); count = getOtherJdbcTemplate () .update ("INSERT into T_AUDITS (id, operation, name, audit_date) values ​​(?,?,?,?)", 0, "INSERT", "foo", new Date ()); assertEquals (1, skaits); // Izmaiņas tiks atgrieztas pēc šīs metodes iziešanas}

Tad MulipleDataSourceTests pārbauda, ​​vai abas darbības tika atceltas, kā parādīts 2. sarakstā:

Saraksts 2. Atgriešanās pārbaude

@AfterTransaction public void checkPostConditions () {int count = getJdbcTemplate (). QueryForInt ("select count (*) from T_FOOS"); // Šīs izmaiņas atcēla testa ietvara assertEquals (0, skaits); count = getOtherJdbcTemplate (). queryForInt ("atlasiet skaitu (*) no T_AUDITS"); // Tas arī atkāpās XA assertEquals (0, skaits) dēļ; }

Lai labāk izprastu, kā darbojas pavasara darījumu pārvaldība un kā to vispār konfigurēt, skatiet pavasara rokasgrāmatu.

XA ar 1PC optimizāciju

Šis modelis ir optimizācija, ko daudzi darījumu pārvaldnieki izmanto, lai izvairītos no 2PC pieskaitāmajām izmaksām, ja darījums ietver vienu resursu. Jūs varētu sagaidīt, ka jūsu lietojumprogrammu serveris to spēs noskaidrot.

XA un pēdējā resursa Gambits

Vēl viena daudzu XA darījumu pārvaldnieku iezīme ir tā, ka viņi joprojām var nodrošināt vienādas atkopšanas garantijas, ja visi resursi, izņemot vienu, ir spējīgi uz XA, kā viņi var, kad viņi visi ir. Viņi to dara, pasūtot resursus un kā izšķirošo balsi izmantojot resursus, kas nav XA. Ja tas neizdodas, tad visus pārējos resursus var atjaunot. Tas ir tuvu 100 procentiem ložu necaurlaidīgam - bet tas nav gluži tas. Un, kad tas neizdodas, tas neizdodas, neatstājot daudz pēdu, ja vien netiek veikti papildu pasākumi (kā tas tiek darīts dažās augšējās klases realizācijās).

Koplietojamo darījumu resursu modelis

Lielisks sarežģītības samazināšanas un caurlaides palielināšanas modelis dažās sistēmās ir XA nepieciešamības atcelšana kopumā, nodrošinot, ka visus sistēmas darījumu resursus faktiski atbalsta viens un tas pats resurss. Tas acīmredzami nav iespējams visos apstrādes lietošanas gadījumos, taču tas ir tikpat stingrs kā XA un parasti daudz ātrāk. Koplietojamo darījumu resursu modelis ir necaurlaidīgs, taču raksturīgs noteiktām platformām un apstrādes scenārijiem.

Vienkāršs un daudziem pazīstams (daudziem) šī modeļa piemērs ir datu bāzes koplietošana Savienojums starp komponentu, kas izmanto objektu relāciju kartēšanu (ORM), ar komponentu, kas izmanto JDBC. Tas notiek, kad izmantojat pavasara darījumu pārvaldniekus, kas atbalsta ORM rīkus, piemēram, hibernācijas, EclipseLink un Java noturības API (JPA). Vienu un to pašu darījumu var droši izmantot ORM un JDBC komponentos, parasti no augšas virza pakalpojuma līmeņa metodes izpilde, kur transakcija tiek kontrolēta.

Vēl viens efektīvs šī modeļa izmantojums ir vienas datu bāzes atjaunināšana ar ziņām (kā tas ir vienkāršā piemērā šī raksta ievadā). Ziņojumapmaiņas un starpprogrammatūras sistēmām dati kaut kur jāuzglabā, bieži vien relāciju datu bāzē. Lai ieviestu šo modeli, nepieciešams tikai norādīt ziņojumapmaiņas sistēmu tajā pašā datu bāzē, kurā tiek izmantoti biznesa dati. Šis modelis ir balstīts uz to, ka ziņojumapmaiņas starpprogrammatūras piegādātājs atklāj glabāšanas stratēģijas detaļas, lai to varētu konfigurēt norādīt uz vienu un to pašu datu bāzi un piesaistīt to pašu darījumu.

Ne visi pārdevēji to padara viegli. Alternatīva, kas darbojas gandrīz jebkurai datu bāzei, ir ziņojumapmaiņai izmantot Apache ActiveMQ un ziņu starpniekā iespraust glabāšanas stratēģiju. To ir diezgan viegli konfigurēt, tiklīdz zināt triku. Tas ir parādīts šajā rakstā shared-jms-db paraugu projekts. Lietojumprogrammas kodam (šajā gadījumā vienības testi) nav jāapzinās, ka šis modelis tiek izmantots, jo pavasara konfigurācijā tas viss ir iespējots deklaratīvi.

Izsaukts vienības tests paraugā SynchronousMessageTriggerAndRollbackTests pārbauda, ​​vai viss darbojas ar sinhrono ziņojumu saņemšanu. The testReceiveMessageUpdateDatabase metode saņem divus ziņojumus un izmanto tos, lai ievietotu divus ierakstus datu bāzē. Kad šī metode tiek izieta, testa ietvars atgriež darījumu, lai jūs varētu pārbaudīt, vai gan ziņojumi, gan datu bāzes atjauninājumi tiek atgriezti, kā parādīts 3. sarakstā:

Saraksts 3. Ziņojumu un datu bāzes atjauninājumu pārbaude

@AfterTransaction public void checkPostConditions () {assertEquals (0, SimpleJdbcTestUtils.countRowsInTable (jdbcTemplate, "T_FOOS")); Sarakstu saraksts = getMessages (); assertEquals (2, saraksts.izmērs ()); }

Vissvarīgākās konfigurācijas iezīmes ir ActiveMQ noturības stratēģija, saistot ziņojumapmaiņas sistēmu ar to pašu Datu avots kā biznesa dati un pavasara karogs JmsTemplate izmanto ziņu saņemšanai. 4. saraksts parāda, kā konfigurēt ActiveMQ noturības stratēģiju:

Saraksts 4. ActiveMQ noturības konfigurēšana

    ...             

5. saraksts parāda pavasara karogu JmsTemplate kas tiek izmantots ziņojumu saņemšanai:

Saraksts 5. Iestatīšana JmsTemplate lietošanai darījumos

 ...   

Bez sessionTransacted = true, JMS sesijas transakcijas API izsaukumi nekad netiks veikti, un ziņojumu saņemšanu nevarēs atsaukt atpakaļ. Svarīgas sastāvdaļas šeit ir iegultais brokeris ar īpašu async = nepatiesa parametru un iesaiņotāju Datu avots kas kopā nodrošina, ka ActiveMQ izmanto to pašu darījumu JDBC Savienojums kā pavasaris.

$config[zx-auto] not found$config[zx-overlay] not found