Ohjelmointi

Hajautetut liiketoimet keväällä, XA: n kanssa ja ilman sitä

Vaikka tavallista on käyttää Java Transaction -sovellusliittymää ja XA-protokollaa hajautettuihin tapahtumiin keväällä, sinulla on muita vaihtoehtoja. Optimaalinen toteutus riippuu käyttämiesi resurssien tyypistä ja kompromisseista, jotka olet valmis tekemään suorituskyvyn, turvallisuuden, luotettavuuden ja tietojen eheyden välillä. Tässä JavaWorld-ominaisuudessa SpringSourcen David Syer opastaa sinut seitsemän mallia hajautettuihin tapahtumiin Spring-sovelluksissa, joista kolmessa on XA ja neljä ilman. Taso: Keskitaso

Spring Frameworkin tuki Java Transaction API: lle (JTA) mahdollistaa sovellusten käyttää hajautettuja tapahtumia ja XA-protokollaa suorittamatta Java EE -säiliössä. Jopa tällä tuella XA on kuitenkin kallis ja voi olla epäluotettava tai hankala hallinnoida. Siksi voi olla tervetullut yllätys, että tietyllä sovellusluokalla voidaan välttää XA: n käyttö kokonaan.

Autan sinua ymmärtämään hajautettujen tapahtumien eri lähestymistapoihin liittyviä näkökohtia analysoimalla seitsemää tapahtumankäsittelymallia ja tarjoamalla koodinäytteet niiden konkreettiseksi tekemiseksi. Esitän kuviot turvallisuuden tai luotettavuuden käänteisessä järjestyksessä, alkaen niistä, joilla on korkein tae tietojen eheydestä ja atomisuudesta yleisimmissä olosuhteissa. Kun siirryt luettelosta alaspäin, lisää varoituksia ja rajoituksia sovelletaan. Mallit ovat myös suunnilleen päinvastaisessa järjestyksessä suorituksen kustannuksista (alkaen kalleimmista). Kuviot ovat kaikki arkkitehtonisia tai teknisiä, toisin kuin liiketoimintamallit, joten en keskity yrityskäytön tapaukseen, vain pienimpään määrään koodia nähdäksesi kunkin mallin toimivan.

Huomaa, että vain kolme ensimmäistä mallia sisältää XA: n, ja ne eivät välttämättä ole saatavana tai hyväksyttäviä suorituskykysyistä. En keskustele XA-malleista yhtä laajalti kuin muut, koska ne on käsitelty muualla, vaikka esitän yksinkertaisen esimerkin ensimmäisestä. Lukemalla tämän artikkelin opit, mitä voi ja mitä ei voi tehdä hajautettujen tapahtumien kanssa ja kuinka ja milloin välttää XA: n käyttöä - ja milloin ei.

Hajautetut liiketoimet ja atomiteetti

A hajautettu liiketoimi on sellainen, johon liittyy useampi kuin yksi kaupallinen resurssi. Esimerkkejä transaktioresursseista ovat liittimet relaatiotietokantojen kanssa viestimiseen ja välitysohjelmien välittämiseen. Usein tällaisella resurssilla on API, joka näyttää jotain alkaa(), palautus (), tehdä(). Java-maailmassa transaktioresurssi näkyy yleensä taustalla olevan alustan tarjoaman tehtaan tuotteena: tietokannalle se on Yhteys (tuottanut Tietolähde) tai Java Persistence API (JPA) EntityManager; Java Message Service (JMS): lle se on a Istunto.

Tyypillisessä esimerkissä JMS-viesti laukaisee tietokannan päivityksen. Aikajanalle hajotettuna onnistunut vuorovaikutus tapahtuu tältä:

  1. Aloita viestintätapahtuma
  2. Vastaanota viesti
  3. Aloita tietokantatapahtuma
  4. Päivitä tietokanta
  5. Suorita tietokantatapahtuma
  6. Suorita viestitapahtuma

Jos päivityksessä tapahtui tietokantavirhe, kuten rajoiterikkomus, toivottava järjestys näyttäisi tältä:

  1. Aloita viestintätapahtuma
  2. Vastaanota viesti
  3. Aloita tietokantatapahtuma
  4. Päivitä tietokanta, epäonnistuu!
  5. Palauta tietokantatapahtuma
  6. Palauta viestitapahtuma

Tällöin viesti palaa väliohjelmistoon viimeisen palautuksen jälkeen ja palaa jossain vaiheessa vastaanotettavaksi toisessa tapahtumassa. Tämä on yleensä hyvä asia, koska muuten sinulla ei ehkä ole kirjaa virheestä. (Mekanismit automaattisen uudelleenyrityksen ja poikkeusten käsittelemiseksi eivät kuulu tämän artikkelin soveltamisalaan.)

Molempien aikataulujen tärkeä piirre on, että ne ovat atomi-, muodostaen yhden loogisen tapahtuman, joka joko onnistuu kokonaan tai epäonnistuu kokonaan.

Mutta mikä takaa, että aikajana näyttää jommallakummalta näistä jaksoista? Joitakin synkronointeja transaktioresurssien välillä on tapahduttava, niin että jos joku sitoutuu, molemmat tekevät, ja päinvastoin. Muuten koko tapahtuma ei ole atominen. Tapahtuma on jaettu, koska mukana on useita resursseja, ja ilman synkronointia se ei ole atominen. Hajautettujen tapahtumien tekniset ja käsitteelliset vaikeudet liittyvät kaikki resurssien synkronointiin (tai sen puutteeseen).

Kolme ensimmäistä alla käsiteltyä mallia perustuvat XA-protokollaan. Koska nämä kuviot on käsitelty laajalti, en aio käsitellä niitä paljon täällä. Ne, jotka tuntevat XA-mallit, saattavat haluta siirtyä eteenpäin jaetun transaktioresurssin malliin.

Täysi XA 2PC: llä

Jos tarvitset luodinkestäviä takuita siitä, että sovelluksesi tapahtumat palautuvat katkoksen jälkeen, mukaan lukien palvelimen kaatuminen, Full XA on ainoa valinta. Jaettu resurssi, jota käytetään tapahtuman synkronointiin tässä tapauksessa, on erityinen tapahtumahallinta, joka koordinoi prosessin tietoja XA-protokollan avulla. Java: ssa, kehittäjän näkökulmasta, protokolla paljastetaan JTA: n kautta UserTransaction.

XA on järjestelmäliittymä, joka on mahdollistava tekniikka, jota useimmat kehittäjät eivät koskaan näe. Heidän on tiedettävä, että se on siellä, mitä se mahdollistaa, mitä se maksaa ja vaikutukset siihen, miten he käyttävät transaktioresursseja. Kustannukset tulevat kaksivaiheisesta sitoutumisprotokollasta (2PC), jota transaktiopäällikkö käyttää varmistaakseen, että kaikki resurssit sopivat tapahtuman tuloksesta ennen sen päättymistä.

Jos sovellus on jousitettu, se käyttää jousta JtaTransactionManager ja kevään deklaratiivinen tapahtumien hallinta piilottamaan taustalla olevan synkronoinnin yksityiskohdat. Kehittäjän ero XA: n käyttämisen ja XA: n käyttämisen välillä on kyse tehdasresurssien määrittämisestä: Tietolähde sovelluksia ja tapahtumanhallinta. Tämä artikkeli sisältää esimerkkisovelluksen ( atomikos-db projekti), joka kuvaa tätä kokoonpanoa. Tietolähde ilmentymät ja tapahtumien hallinta ovat sovelluksen ainoat XA- tai JTA-kohtaiset elementit.

Jos haluat nähdä näytteen toimivan, suorita yksikötestit kohdassa com.springsource.open.db. Yksinkertainen MulipleDataSourceTests class vain lisää tiedot kahteen tietolähteeseen ja käyttää sitten Spring Integration -tukiominaisuuksia tapahtuman palauttamiseen, kuten luettelossa 1 on esitetty:

Luettelo 1. Tapahtumien palautus

@Transactional @Test public void testInsertIntoTwoDataSources () heittää poikkeuksen {int count = getJdbcTemplate (). Update ("INSERT into T_FOOS (id, name, foo_date) values ​​(?,?, Null)", 0, "foo"); assertEquals (1, määrä); count = getOtherJdbcTemplate () .update ("INSERT into T_AUDITS (id, operation, name, audit_date) values ​​(?,?,?,?)", 0, "INSERT", "foo", new Date ()); assertEquals (1, määrä); // Muutokset palautuvat tämän menetelmän poistuttua}

Sitten MulipleDataSourceTests tarkistaa, että molemmat toiminnot palautettiin, kuten luettelossa 2 on esitetty:

Listaus 2. Palautuksen tarkistaminen

@AfterTransaction public void checkPostConditions () {int count = getJdbcTemplate (). QueryForInt ("valitse määrä (*) T_FOOSista"); // Testikehys assertEquals (0, count) palautti tämän muutoksen; count = getOtherJdbcTemplate (). queryForInt ("valitse määrä (*) joukosta T_AUDITS"); // Tämä palasi myös takaisin XA assertEquals (0, count); }

Spring-oppaasta saat paremman käsityksen siitä, miten kevään tapahtumien hallinta toimii ja miten se määritetään yleensä.

XA 1PC-optimoinnilla

Tämä malli on optimointi, jota monet tapahtumien ylläpitäjät käyttävät välttääkseen 2PC: n yleiskustannuksia, jos tapahtuma sisältää yhden resurssin. Luulisi, että sovelluspalvelimesi pystyy selvittämään tämän.

XA ja viimeinen resurssi Gambit

Monien XA-tapahtumien hallinnoijien toinen ominaisuus on, että ne voivat silti tarjota samat palautustakuut, kun kaikki resurssit paitsi yksi ovat XA-yhteensopivia kuin he kaikki. He tekevät tämän tilaamalla resurssit ja käyttämällä ei-XA-resursseja ratkaisevana äänenä. Jos se epäonnistuu, kaikki muut resurssit voidaan palauttaa. Se on lähes 100 prosenttia luodinkestävä - mutta ei aivan. Ja kun se epäonnistuu, se epäonnistuu jättämättä paljon jälkeä, ellei ylimääräisiä vaiheita toteuteta (kuten tehdään joissakin ylimmän tason toteutuksissa).

Jaetun tapahtuman resurssimalli

Suuri malli monimutkaisuuden vähentämiselle ja läpimenon lisäämiselle joissakin järjestelmissä on poistaa XA: n tarve kokonaan varmistamalla, että kaikki järjestelmän transaktioresurssit ovat tosiasiallisesti saman resurssin takana. Tämä ei selvästikään ole mahdollista kaikissa käsittelyn käyttötapauksissa, mutta se on yhtä vakaa kuin XA ja yleensä paljon nopeampi. Jaettu transaktioresurssimalli on luodinkestävä, mutta erityinen tietyille alustoille ja käsittelyskenaarioille.

Yksinkertainen ja monille tuttu esimerkki tästä mallista on tietokannan jakaminen Yhteys objektisuhdekartoitusta (ORM) käyttävän komponentin ja JDBC: tä käyttävän komponentin välillä. Näin tapahtuu, kun käytät Spring-tapahtumahallintoja, jotka tukevat ORM-työkaluja, kuten Hibernate, EclipseLink ja Java Persistence API (JPA). Samaa tapahtumaa voidaan turvallisesti käyttää ORM- ja JDBC-komponenttien välillä, yleensä ylhäältäpäin ohjattuna palvelutason menetelmän suorituksella, jossa tapahtumaa hallitaan.

Toinen tämän mallin tehokas käyttö on yksittäisen tietokannan viestiohjattu päivitys (kuten tämän artikkelin johdannossa olevassa yksinkertaisessa esimerkissä). Viestintä-väliohjelmistojärjestelmien on tallennettava tietonsa jonnekin, usein relaatiotietokantaan. Tämän mallin toteuttamiseksi tarvitsee vain osoittaa viestijärjestelmä samaan tietokantaan, johon yritystiedot menevät. Tämä malli perustuu siihen, että viestintä- ja väliohjelmistotoimittaja paljastaa tallennusstrategiansa yksityiskohdat, jotta se voidaan määrittää osoittamaan samaan tietokantaan ja kytkeytymään samaan tapahtumaan.

Kaikki toimittajat eivät tee tästä helppoa. Vaihtoehto, joka toimii melkein missä tahansa tietokannassa, on käyttää Apache ActiveMQ: ta viestien lähettämiseen ja liittää tallennusstrategia viestivälittäjään. Tämä on melko helppo määrittää, kun tiedät temppun. Se on osoitettu tässä artikkelissa jaettu-jms-db näyteprojekti. Sovelluskoodin (tässä tapauksessa yksikötestit) ei tarvitse olla tietoinen siitä, että tämä malli on käytössä, koska se kaikki on otettu käyttöön deklaratiivisesti jousen kokoonpanossa.

Näytteen yksikötesti kutsutaan SynchronousMessageTriggerAndRollbackTests varmistaa, että kaikki toimii synkronisen viestin vastaanoton kanssa. testReceiveMessageUpdateDatabase method vastaanottaa kaksi viestiä ja käyttää niitä kahden tietueen lisäämiseen tietokantaan. Kun tämä menetelmä poistuu, testikehys palauttaa tapahtuman takaisin, joten voit varmistaa, että sekä viestit että tietokantapäivitykset palautetaan, kuten luettelossa 3 on esitetty:

Listaus 3. Viestien ja tietokantapäivitysten palauttamisen tarkistaminen

@AfterTransaction public void checkPostConditions () {assertEquals (0, SimpleJdbcTestUtils.countRowsInTable (jdbcTemplate, "T_FOOS")); List list = getMessages (); assertEquals (2, list.size ()); }

Konfiguroinnin tärkeimmät ominaisuudet ovat ActiveMQ-pysyvyysstrategia, joka linkittää viestijärjestelmän samaan Tietolähde kuin yritystiedot ja kevään lippu JmsTemplate käytetään viestien vastaanottamiseen. Luettelossa 4 näkyy, kuinka ActiveMQ-pysyvyysstrategia määritetään:

Luettelo 4. ActiveMQ-pysyvyyden määrittäminen

    ...             

Luettelossa 5 näkyy kevään lippu JmsTemplate jota käytetään viestien vastaanottamiseen:

Listaus 5. JmsTemplate kaupalliseen käyttöön

 ...   

Ilman sessionTransacted = tosi, JMS-istunnon tapahtuman API-kutsuja ei koskaan soiteta eikä viestien vastaanottoa voida palauttaa takaisin. Tärkeät ainesosat ovat upotettu välittäjä erityisellä asynk = väärä parametri ja kääre Tietolähde jotka yhdessä varmistavat, että ActiveMQ käyttää samaa kaupallista JDBC: tä Yhteys kuten kevät.

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