En guide til Atomikos

1. Introduksjon

Atomikos er et transaksjonsbibliotek for Java-applikasjoner. I denne opplæringen vil vi forstå hvorfor og hvordan du bruker Atomikos.

I prosessen vil vi også gå gjennom det grunnleggende om transaksjoner og hvorfor vi trenger dem.

Deretter lager vi et enkelt program med transaksjoner som bruker forskjellige API-er fra Atomikos.

2. Forstå det grunnleggende

Før vi diskuterer Atomikos, la oss forstå hva nøyaktig transaksjoner er og noen få konsepter relatert til dem. Enkelt sagt, en transaksjon er en logisk arbeidsenhet hvis effekt er synlig utenfor transaksjonen enten i sin helhet eller ikke i det hele tatt.

La oss ta et eksempel for å forstå dette bedre. En typisk detaljhandelsapplikasjon reserverer varelageret og bestiller deretter:

Her vil vi at disse to operasjonene enten skal skje sammen eller ikke skje i det hele tatt. Vi kan oppnå dette ved å pakke inn disse operasjonene i en enkelt transaksjon.

2.1. Lokal vs. distribuert transaksjon

En transaksjon kan involvere flere uavhengige operasjoner. Disse operasjonene kan utføre på samme ressurs eller forskjellige ressurser. Vi refererer til de deltakende komponentene i en transaksjon som en database som en ressurs her.

Transaksjoner innenfor en enkelt ressurs er kjent lokal transaksjon, mens de som gyter på tvers av flere ressurser er kjent som den distribuerte transaksjonen:

Her kan lager og ordrer være to tabeller i samme database, eller de kan være to forskjellige databaser - muligens kjører på forskjellige maskiner helt.

2.2. XA-spesifikasjon og Java Transaction API

XA refererer til eXtended Architecture, som er en spesifikasjon for distribuert transaksjonsbehandling. De Målet med XA er å gi atomisitet i globale transaksjoner som involverer heterogene komponenter.

XA-spesifikasjon gir integritet gjennom en protokoll kjent som en to-fase forpliktelse. To-fase forpliktelse er en mye brukt distribuert algoritme for å lette beslutningen om å begå eller tilbakeføre en distribuert transaksjon.

Java Transaction API (JTA) er en Java Enterprise Edition API utviklet under Java Community Process. Den gjør det mulig for Java-applikasjoner og applikasjonsservere å utføre distribuerte transaksjoner på tvers av XA-ressurser.

JTA er modellert rundt XA-arkitektur, og utnytter to-fase forpliktelse. JTA spesifiserer standard Java-grensesnitt mellom en transaksjonsbehandling og de andre partene i en distribuert transaksjon.

3. Introduksjon til Atomikos

Nå som vi har gått gjennom det grunnleggende om transaksjoner, er vi klare til å lære Atomikos. I denne delen vil vi forstå hva Atomikos er og hvordan det forholder seg til konsepter som XA og JTA. Vi vil også forstå arkitekturen til Atomikos og gå gjennom produkttilbudene.

3.1. Hva er Atomikos

Som vi har sett, gir JTA grensesnitt i Java for å bygge applikasjoner med distribuerte transaksjoner. Nå er JTA bare en spesifikasjon og tilbyr ingen implementering. For oss for å kjøre et program der vi utnytter JTA, trenger vi en implementering av JTA. En slik implementering kalles en transaksjonsleder.

Vanligvis gir applikasjonsserveren en standardimplementering av transaksjonsadministratoren. For eksempel når det gjelder Enterprise Java Beans (EJB), administrerer EJB-containere transaksjonsadferd uten noen eksplisitt inngripen fra applikasjonsutviklere. I mange tilfeller er dette imidlertid ikke ideelt, og vi trenger kanskje direkte kontroll over transaksjonen uavhengig av applikasjonsserveren.

Atomikos er en lett transaksjonssjef for Java som gjør at applikasjoner som bruker distribuerte transaksjoner kan være selvstendige. I hovedsak trenger ikke søknaden vår å stole på en tungvektskomponent som en applikasjonsserver for transaksjoner. Dette bringer konseptet med distribuerte transaksjoner nærmere en skyinnfødt arkitektur.

3.2. Atomikos Arkitektur

Atomikos er hovedsakelig bygget som en JTA-transaksjonsleder, og dermed implementerer XA-arkitektur med en to-fase forpliktelsesprotokoll. La oss se en arkitektur på høyt nivå med Atomikos:

Her legger Atomikos til rette for en to-fase-forpliktelsesbasert transaksjon som spenner over en database og en meldingskø.

3.3. Atomikos produkttilbud

Atomikos er en distribuert transaksjonsleder som tilbyr flere funksjoner enn hva JTA / XA pålegger. Den har et open source-produkt og et mye mer omfattende kommersielt tilbud:

  • Transaksjoner Essensielle: Atomikos ' open source-produkt som gir JTA / XA transaksjonsbehandling for Java-applikasjoner arbeider med databaser og meldingskøer. Dette er mest nyttig for test- og evalueringsformål.
  • ExtremeTransactions: the kommersielt tilbud av Atomikos, som tilbyr distribuerte transaksjoner på tvers av sammensatte applikasjoner, inkludert REST-tjenester bortsett fra databaser og meldingskøer. Dette er nyttig for å bygge applikasjoner som utfører Extreme Transaction Processing (XTP).

I denne opplæringen bruker vi TransactionsEssentials-biblioteket til å bygge og demonstrere funksjonene til Atomikos.

4. Sette opp Atomikos

Som vi har sett tidligere, er det et av høydepunktene i Atomikos det er en innebygd transaksjonstjeneste. Hva dette betyr er at vi kan kjøre den i samme JVM som applikasjonen vår. Dermed er det ganske greit å sette opp Atomikos.

4.1. Avhengigheter

Først må vi sette opp avhengighetene. Her er alt vi trenger å gjøre å erklære avhengighetene i vår Maven pom.xml fil:

 com.atomikos transaksjoner-jdbc 5.0.6 com.atomikos transaksjoner-jms 5.0.6 

Vi bruker Atomikos-avhengigheter for JDBC og JMS i dette tilfellet, men lignende avhengigheter er tilgjengelig på Maven Central for andre XA-klageressurser.

4.2. Konfigurasjoner

Atomikos tilbyr flere konfigurasjonsparametere, med fornuftige standardverdier for hver av dem. Den enkleste måten å overstyre disse parametrene er å gi en transaksjoner. eiendommer filen i klassestien. Vi kan legge til flere parametere for initialisering og drift av transaksjonstjenesten. La oss se en enkel konfigurasjon for å overstyre katalogen der loggfiler opprettes:

com.atomikos.icatch.file = sti_til_fil

På samme måte er det andre parametere som vi kan bruke til å kontrollere tidsavbrudd for transaksjoner, angi unike navn for applikasjonen vår eller definere nedleggelsesatferd.

4.3. Databaser

I vår veiledning bygger vi en enkel detaljhandelapplikasjon, som den vi beskrev tidligere, som reserverer lager og deretter bestiller. Vi bruker en relasjonsdatabase for enkelhets skyld. Videre bruker vi flere databaser for å demonstrere distribuerte transaksjoner. Derimot, dette kan veldig godt utvide til andre XA-klageressurser som meldingskøer og emner.

Vår varedatabase vil ha en enkel tabell for å være vert for produktbeholdninger:

OPPRETT TABELLOPPBEVARING (productId VARCHAR PRIMARY KEY, balance INT);

Og bestillingsdatabasen vår vil ha en enkel tabell for å være vert for bestillinger:

OPPRETT BORDORDRE (ordre-VARCHAR PRIMÆR NØKKEL, produktId VARCHAR, mengde INT IKKE NULL CHECK (mengde <= 5));

Dette er et veldig grunnleggende databaseskjema og bare nyttig for demonstrasjonen. Det er imidlertid viktig å merke seg at vår skjemabegrensning ikke tillater ordre med en produktmengde på mer enn fem.

5. Arbeide med Atomikos

Nå er vi klare til å bruke et av Atomikos-bibliotekene til å bygge applikasjonen vår med distribuerte transaksjoner. I de følgende underavsnittene bruker vi de innebygde Atomikos ressurskortene for å koble til våre back-end databasesystemer. Dette er den raskeste og enkleste måten å komme i gang med Atomikos.

5.1. Instantierende UserTransaction

Vi vil utnytte JTA UserTransaction for å avgrense transaksjonsgrenser. Alle andre trinn relatert til transaksjonstjeneste blir automatisk ivaretatt. Dette inkluderer å verve og fjerne ressurser med transaksjonstjenesten.

For det første må vi sette i gang a UserTransaction fra Atomikos:

UserTransactionImp utx = ny UserTransactionImp ();

5.2. Instantierende Datakilde

Deretter må vi sette i gang a Datakilde fra Atomikos. Det er to versjoner av Datakilde som Atomikos gjør tilgjengelig.

Den første, AtomikosDataSourceBean, er klar over en underliggende XADataSource:

AtomikosDataSourceBean dataSource = ny AtomikosDataSourceBean ();

Samtidig som AtomikosNonXADataSourceBean bruker hvilken som helst vanlig JDBC-førerklasse:

AtomikosNonXADataSourceBean dataSource = ny AtomikosNonXADataSourceBean ();

Som navnet antyder, AtomikosNonXADataSource er ikke XA-kompatibel. Derfor kan ikke transaksjoner utført med en slik datakilde garanteres å være atomare. Så hvorfor skulle vi noen gang bruke dette? Vi kan ha en database som ikke støtter XA-spesifikasjon. Atomikos forbyr ikke oss å bruke en slik datakilde og prøver fortsatt å gi atomisitet hvis det er en slik datakilde i transaksjonen. Denne teknikken ligner på Last Resource Gambit, en variant av den to-fase forpliktelsesprosessen.

Videre må vi konfigurere Datakilde avhengig av database og driver.

5.3. Utfører databaseoperasjoner

Når den er konfigurert, er den ganske enkel å bruke Datakilde innenfor rammen av en transaksjon i søknaden vår:

public void placeOrder (String productId, int amount) kaster Unntak {String orderId = UUID.randomUUID (). toString (); boolsk tilbakeføring = falsk; prøv {utx.begin (); Connection inventoryConnection = inventoryDataSource.getConnection (); Connection orderConnection = orderDataSource.getConnection (); Uttalelse s1 = lagerConnection.createStatement (); Streng q1 = "oppdater beholdning innstilt saldo = saldo -" + beløp + "der productId = '" + productId + "'"; s1.executeUpdate (q1); s1.close (); Uttalelse s2 = orderConnection.createStatement (); Streng q2 = "sett inn i ordreværdier ('" + orderId + "', '" + productId + "'," + beløp + ")"; s2.executeUpdate (q2); s2.close (); inventarConnection.close (); orderConnection.close (); } catch (Unntak e) {rollback = true; } til slutt {if (! rollback) utx.commit (); annet utx.rollback (); }}

Her oppdaterer vi databasetabellene for lager og ordre innenfor transaksjonsgrensen. Dette gir automatisk fordelen av at disse operasjonene skjer atomisk.

5.4. Testing av transaksjonsatferd

Til slutt må vi kunne teste søknaden vår med enkle enhetstester for å validere at transaksjonsadferden er som forventet:

@Test offentlig ugyldig testPlaceOrderSuccess () kaster unntak {int beløp = 1; lang initialBalance = getBalance (lagerDataSource, productId); Søknadssøknad = ny søknad (inventarDataSource, orderDataSource); application.placeOrder (productId, beløp); long finalBalance = getBalance (inventoryDataSource, productId); assertEquals (initialBalance - amount, finalBalance); } @Test offentlig ugyldig testPlaceOrderFailure () kaster unntak {int beløp = 10; lang initialBalance = getBalance (lagerDataSource, productId); Søknadssøknad = ny søknad (inventarDataSource, orderDataSource); application.placeOrder (productId, beløp); long finalBalance = getBalance (inventoryDataSource, productId); assertEquals (initialBalance, finalBalance); }

Her, Vi forventer en gyldig ordre for å redusere varelageret, mens vi forventer at en ugyldig ordre vil la varen forbli uendret. Vær oppmerksom på at i henhold til databasebegrensningen, betraktes enhver ordre med et antall på mer enn fem av et produkt som en ugyldig ordre.

5.5. Avansert bruk av Atomikos

Eksemplet ovenfor er den enkleste måten å bruke Atomikos og kanskje tilstrekkelig for de fleste av kravene. Imidlertid er det andre måter vi kan bruke Atomikos til å bygge applikasjonen vår på. Mens noen av disse alternativene gjør Atomikos enkle å bruke, tilbyr andre mer fleksibilitet. Valget avhenger av våre krav.

Det er det selvfølgelig ikke nødvendig å alltid bruke Atomikos-adaptere for JDBC / JMS. Vi kan velge å bruke Atomikos transaksjonsleder mens vi jobber direkte med XAResource. I så fall må vi imidlertid eksplisitt ta vare på verving og avnotering XAResource forekomster med transaksjonstjenesten.

Atomikos gjør det også mulig å bruke mer avanserte funksjoner gjennom et proprietært grensesnitt, UserTransactionService. Ved hjelp av dette grensesnittet kan vi eksplisitt registrere ressurser for gjenoppretting. Dette gir oss finkornet kontroll over hvilke ressurser som skal gjenvinnes, hvordan de skal gjenvinnes, og når utvinning skal skje.

6. Integrering av Atomikos

Mens Atomikos gir utmerket støtte for distribuerte transaksjoner, er det ikke alltid praktisk å jobbe med slike API-er på lavt nivå. For å fokusere på virksomhetsdomenet og unngå rot av kjeleplatekode, trenger vi ofte støtte fra forskjellige rammer og biblioteker. Atomikos støtter de fleste av de populære Java-rammene relatert til back-end integrasjoner. Vi vil utforske et par av dem her.

6.1. Atomikos With Spring og Datakilde

Spring er en av de populære rammene i Java som gir en Inversion of Control (IoC) container. Spesielt har den også fantastisk støtte for transaksjoner. Det tilbyr deklarativ transaksjonsadministrasjon ved bruk av Aspect-Oriented Programming (AOP) teknikker.

Spring støtter flere API-er for transaksjoner, inkludert JTA for distribuerte transaksjoner. Vi kan bruke Atomikos som vår JTA-transaksjonsleder innen våren uten mye anstrengelse. Viktigst, søknaden vår forblir ganske agnostisk for Atomikos, takket være våren.

La oss se hvordan vi kan løse vårt forrige problem, denne gangen ved å utnytte våren. Vi begynner med å skrive om applikasjon klasse:

public class Application {private DataSource inventoryDataSource; privat DataSource orderDataSource; offentlig applikasjon (DataSource inventoryDataSource, DataSource orderDataSource) {this.inventoryDataSource = lagerDataSource; this.orderDataSource = orderDataSource; } @Transactional (rollbackFor = Exception.class) public void placeOrder (String productId, int amount) kaster Unntak {String orderId = UUID.randomUUID (). ToString (); Connection inventoryConnection = inventoryDataSource.getConnection (); Connection orderConnection = orderDataSource.getConnection (); Uttalelse s1 = lagerConnection.createStatement (); Streng q1 = "oppdater beholdning innstilt saldo = saldo -" + beløp + "der productId = '" + productId + "'"; s1.executeUpdate (q1); s1.close (); Uttalelse s2 = orderConnection.createStatement (); Streng q2 = "sett inn i ordreværdier ('" + orderId + "', '" + productId + "'," + beløp + ")"; s2.executeUpdate (q2); s2.close (); inventarConnection.close (); orderConnection.close (); }}

Som vi kan se her, det meste av den transaksjonsrelaterte kjeleplatekoden er erstattet av en enkelt kommentar på metodenivå. Dessuten tar Spring seg av å instantere og injisere Datakilde, som søknaden vår avhenger av.

Selvfølgelig må vi tilby relevante konfigurasjoner til våren. Vi kan bruke en enkel Java-klasse for å konfigurere disse elementene:

@Configuration @EnableTransactionManagement public class Config {@Bean (initMethod = "init", destroyMethod = "close") offentlig AtomikosDataSourceBean lagerDataSource () {AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean (); // Konfigurer databasen som inneholder datadatakilde for ordre; } @Bean (initMethod = "init", destroyMethod = "close") offentlig AtomikosDataSourceBean orderDataSource () {AtomikosDataSourceBean dataSource = ny AtomikosDataSourceBean (); // Konfigurer databasen som inneholder datadatakilde for ordre; } @Bean (initMethod = "init", destroyMethod = "close") offentlig UserTransactionManager userTransactionManager () kaster SystemException {UserTransactionManager userTransactionManager = ny UserTransactionManager (); userTransactionManager.setTransactionTimeout (300); userTransactionManager.setForceShutdown (true); returner userTransactionManager; } @Bean public JtaTransactionManager jtaTransactionManager () kaster SystemException {JtaTransactionManager jtaTransactionManager = ny JtaTransactionManager (); jtaTransactionManager.setTransactionManager (userTransactionManager ()); jtaTransactionManager.setUserTransaction (userTransactionManager ()); returner jtaTransactionManager; } @Bean offentlig søknadssøknad () {returner ny søknad (lagerDataSource (), orderDataSource ()); }}

Her konfigurerer vi AtomikosDataSourceBean for de to forskjellige databasene som inneholder lager- og ordredataene våre. Videre tilbyr vi også den nødvendige konfigurasjonen for JTA-transaksjonsadministratoren.

Nå kan vi teste søknaden vår om transaksjonsadferd som før. Igjen, vi bør validere at en gyldig ordre reduserer lagerbeholdningen, mens en ugyldig ordre etterlater den uendret.

6.2. Atomikos With Spring, JPA og Hibernate

Mens våren har hjulpet oss til å kutte ned kjeleplatekoden til en viss grad, er den fortsatt ganske ordentlig. Noen verktøy kan gjøre arbeidet med relasjonsdatabaser i Java enda enklere. Java Persistence API (JPA) er en spesifikasjon som beskriver styring av relasjonsdata i Java-applikasjoner. Dette forenkler datatilgang og manipuleringskode i stor grad.

Dvalemodus er en av de mest populære implementeringene av JPA-spesifikasjonen. Atomikos har stor støtte for flere JPA-implementeringer, inkludert dvalemodus. Som før er søknaden vår fortsatt agnostisk for Atomikos så vel som dvalemodus, takket være Spring og JPA!

La oss se hvordan Spring, JPA og Hibernate kan gjøre søknaden vår enda mer kortfattet og samtidig gi fordelene ved distribuerte transaksjoner gjennom Atomikos. Som før vil vi begynne med å skrive om applikasjon klasse:

offentlig klasse Søknad {@Autowired private InventoryRepository inventoryRepository; @Autowired privat OrderRepository orderRepository; @Transactional (rollbackFor = Exception.class) public void placeOrder (String productId, int amount) kaster SQLException {String orderId = UUID.randomUUID (). ToString (); Lagerbeholdning = lagerRepository.findOne (productId); lager.setBalance (lager.getBalance () - beløp); inventoryRepository.save (inventar); Ordreordre = ny ordre (); order.setOrderId (orderId); order.setProductId (productId); order.setAmount (ny Long (beløp)); orderRepository.save (ordre); }}

Som vi kan se, har vi ikke å gjøre med noen database-APIer på lavt nivå nå. For at denne magien skal fungere, trenger vi imidlertid å konfigurere Spring Data JPA-klasser og konfigurasjoner. Vi begynner med å definere domenenhetene våre:

@Entity @Table (name = "LAGER") offentlig klasse Inventory {@Id private String productId; privat Lang balanse; // Getters og Setters}
@Entity @Table (name = "ORDERS") offentlig klasse Bestill {@Id privat streng orderId; private String productId; @Max (5) privat Langt beløp; // Getters og Setters}

Deretter må vi skaffe lagringsplassene for disse enhetene:

@Repository public interface InventoryRepository utvider JpaRepository {} @Repository public interface OrderRepository utvider JpaRepository {}

Dette er ganske enkle grensesnitt, og Spring Data tar seg av å utdype disse med faktisk kode for å jobbe med databaseenheter.

Til slutt må vi tilby de relevante konfigurasjonene for en datakilde for både lager- og ordrebaser og transaksjonsadministratoren:

@Configuration @EnableJpaRepositories (basePackages = "com.baeldung.atomikos.spring.jpa.inventory", entityManagerFactoryRef = "lagerEntityManager", transactionManagerRef = "transactionManager") offentlig klasse InventoryConfig {@Bean (initMethod = "init" ") offentlig AtomikosDataSourceBean lagerDataSource () {AtomikosDataSourceBean dataSource = ny AtomikosDataSourceBean (); // Konfigurer datakildens returdataSource; } @Bean public EntityManagerFactory lagerEntityManager () {HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter (); LocalContainerEntityManagerFactoryBean fabrikken = ny LocalContainerEntityManagerFactoryBean (); factory.setJpaVendorAdapter (leverandøradapter); // Konfigurer enhetslederens fabrikkretur fabrikk.getObject (); }}
@Configuration @EnableJpaRepositories (basePackages = "com.baeldung.atomikos.spring.jpa.order", entityManagerFactoryRef = "orderEntityManager", transactionManagerRef = "transactionManager") offentlig klasse OrderConfig {@Bean (initMethod = "init", destroyMeth ") offentlig AtomikosDataSourceBean orderDataSource () {AtomikosDataSourceBean dataSource = ny AtomikosDataSourceBean (); // Konfigurer datakildens returdataSource; } @Bean public EntityManagerFactory orderEntityManager () {HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter (); LocalContainerEntityManagerFactoryBean fabrikken = ny LocalContainerEntityManagerFactoryBean (); factory.setJpaVendorAdapter (leverandøradapter); // Konfigurer enhetsleder fabrikkretur fabrikk.getObject (); }}
@Configuration @EnableTransactionManagement public class Config {@Bean (initMethod = "init", destroyMethod = "close") offentlig UserTransactionManager userTransactionManager () kaster SystemException {UserTransactionManager userTransactionManager = ny UserTransactionManager (); userTransactionManager.setTransactionTimeout (300); userTransactionManager.setForceShutdown (true); returner userTransactionManager; } @Bean offentlig JtaTransactionManager transactionManager () kaster SystemException {JtaTransactionManager jtaTransactionManager = ny JtaTransactionManager (); jtaTransactionManager.setTransactionManager (userTransactionManager ()); jtaTransactionManager.setUserTransaction (userTransactionManager ()); returner jtaTransactionManager; } @Bean offentlig søknadssøknad () {returner ny søknad (); }}

Dette er fremdeles ganske mye konfigurasjon som vi må gjøre. Dette er delvis fordi vi konfigurerer Spring JPA for to separate databaser. Vi kan også redusere disse konfigurasjonene ytterligere gjennom Spring Boot, men det er utenfor omfanget av denne opplæringen.

Som før kan vi teste søknaden vår for samme transaksjonsatferd. Det er ikke noe nytt denne gangen, bortsett fra det faktum at vi bruker Spring Data JPA med Hibernate nå.

7. Atomikos Beyond JTA

Mens JTA gir utmerket transaksjonsstøtte for distribuerte systemer, må disse systemene være XA-klage som de fleste relasjonsdatabaser eller meldingskøer. Derimot, JTA er ikke nyttig hvis et av disse systemene ikke støtter XA-spesifikasjon for en to-fase forpliktelsesprotokoll. Flere ressurser faller inn under denne kategorien, spesielt innenfor en mikrotjenestearkitektur.

Flere alternative protokoller støtter distribuerte transaksjoner. En av disse er en variant av tofaset forpliktelsesprotokoll som benytter kompensasjoner. Slike transaksjoner har en avslappet isolasjonsgaranti og er kjent som kompensasjonsbaserte transaksjoner. Deltakerne forplikter de enkelte delene av transaksjonen i selve første fasen, og tilbyr en kompensasjonshåndterer for en mulig tilbakeføring i andre fase.

Det er flere designmønstre og algoritmer for å implementere en kompensasjonsbasert transaksjon. For eksempel er Sagas et slikt populært designmønster. Imidlertid er de vanligvis komplekse å implementere og være utsatt for feil.

Atomikos tilbyr en variant av kompensasjonsbasert transaksjon kalt Try-Confirm / Cancel (TCC). TCC tilbyr bedre forretningsemantikk til enhetene under en transaksjon. Dette er imidlertid bare mulig med avansert arkitekturstøtte fra deltakerne, og TCC er bare tilgjengelig under Atomikos kommersielle tilbud, ExtremeTransactions.

8. Alternativer til Atomikos

Vi har gått gjennom nok av Atomikos til å sette pris på hva den har å tilby. Videre er det et kommersielt tilbud fra Atomikos med enda kraftigere funksjoner. Atomikos er imidlertid ikke det eneste alternativet når det gjelder å velge en JTA-transaksjonsleder. Det er noen få andre troverdige alternativer å velge mellom. La oss se hvordan de har det mot Atomikos.

8.1. Narayana

Narayana er kanskje en av de eldste distribuerte transaksjonsansvarlige med åpen kildekode og administreres for tiden av Red Hat. Det har blitt brukt mye i bransjen, og det har utviklet seg gjennom samfunnstøtte og påvirket flere spesifikasjoner og standarder.

Narayana gir støtte for et bredt spekter av transaksjonsprotokoller som JTA, JTS, Web-Services og REST, for å nevne noen. Videre kan Narayana legges inn i et bredt spekter av containere.

Sammenlignet med Atomikos gir Narayana stort sett alle funksjonene til en distribuert transaksjonsleder. I mange tilfeller er Narayana mer fleksibel å integrere og bruke i applikasjoner. For eksempel har Narayana språkbindinger for både C / C ++ og Java. Dette koster imidlertid ekstra kompleksitet, og Atomikos er relativt enklere å konfigurere og bruke.

8.2. Bitronix

Bitronix er en fullt fungerende XA-transaksjonsleder som leverer alle tjenester som kreves av JTA API. Det er viktig at Bitronix er et innebygd transaksjonsbibliotek som gir omfattende og nyttig feilrapportering og logging. For en distribuert transaksjon gjør dette det lettere å undersøke feil. Videre har den utmerket støtte for Spring's transaksjonsevner og fungerer med minimale konfigurasjoner.

Sammenlignet med Atomikos er Bitronix et open source-prosjekt og har ikke et kommersielt tilbud med produktstøtte. De viktigste funksjonene som er en del av Atomikos kommersielle tilbud, men som mangler i Bitronix, inkluderer støtte for mikrotjenester og deklarativ elastisk skaleringsevne.

9. Konklusjon

For å oppsummere, i denne opplæringen, gikk vi gjennom de grunnleggende detaljene i transaksjoner. Vi forsto hva distribuerte transaksjoner er, og hvordan et bibliotek som Atomikos kan gjøre det lettere å utføre dem. I prosessen utnyttet vi Atomikos APIer for å lage en enkel applikasjon med distribuerte transaksjoner.

Vi forsto også hvordan Atomikos fungerer med andre populære Java-rammer og biblioteker. Til slutt gikk vi gjennom noen av alternativene til Atomikos som er tilgjengelige for oss.

Som vanlig kan kildekoden for denne artikkelen finnes på GitHub.


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