Życie bez transakcji ?

0

Cześć, nie jestem pewien czy jest to dobry dział, ale postanowiłem założyć temat tutaj.

Od sierpnia zaczynam uczyć się Vert.Xa oraz programowania asynchronicznego w praktyce a nie w teorii - nareszcie będzie trochę wolnego czasu po semestrze ;) Po kilkunastu godzinach czytania / oglądania prezentacji zauważyłem pewną rzecz. Ci wszyscy goście mówią jakie to jest fajne / ciekawe / inne - super, też się jaram, jednak albo to ja byłem bardzo nieuważny, albo ja poświęciłem na to zbyt mało czasu.

Do rzeczy - jak w aplikacjach opartych o rozwiązania "message driven" i różnych async frameworkach zapewnić spójność danych w razie failu ? Jestem tego świadomy, że to raczej nie przeznaczenie tychże frameworków, ale bardziej czegoś a'la DAO (Slick itp.) lub zwyczajnie nie potrafię sobie tego wyobrazić - jednej transakcji, która wykrzaczy się w razie wyjątku.

W Springu sprawa jest nadzwyczaj prosta - @Transactional lub programowo odpalamy transakcje. W modelu jednowątkowym wszystko jest proste.

Zatem pytanie moje brzmi - jak ogarnąć transakcje w aplikacjach opartych o chociażby Akke lub Vert.Xa ? A może ( i skłaniam się bardziej do tej wersji) - po prostu zła architektura i stos technologiczny skoro potrzebujemy transakcji ?

0

w przypadku akki, gdzie wszystko powinno być oddelegowane do "podegających aktorów", jeżeli któryś się wykrzaczy, to supervisor powinien zareagować - zastąpić wykrzaczonego aktora nowym lub samemu się wykrzaczyć, żeby znowu jego supervisor podjął decyzje.

wyhaczyłem jakiś link, może się przydać:
https://arstechnica.com/civis/viewtopic.php?f=20&t=1269913

0

Hmmm, a co w przypadku gdy chcę wywołać po sobie 3 "serwisy", które zwracają - powiedzmy twory Future'pochodne. Zwykłe zapisy do SQLki, wykrzacza się jeden z nich. Jak to "owinąć" w transakcję ? Trudno jest mi to sobie wyobrazić w jakiejkolwiek z dostępnych technologii.

PS. Nie pogardzę jakimś banalnym kodzikiem z githuba / czegokolwiek ;)

1

Hasła na dziś

  1. Event Sourcing – zapisujesz dane w poszczególnych krokach zachowując kolejność „zdarzeń”.
  2. CQRS – szyli segregacja poleceń i zapytań. W połączeniu z ES, odpytujesz tylko o „udane” wykonania procesu.

Jeśli chodzi o „puchnięcie” bazy danych to w przypadku ES zazwyczaj robi się coś w rodzaju commit pointów, gdzie utrwala się stan „świata” m.in. usuwając zbędne dane.

1

@Koziołek mówisz o tym żeby zapisywać eventy które dzieją się podczas jakiegos etapu który normalnie objęty byłby transakcją i w razie failu odczytac te eventy i cofać zmiany? wtedy każdy event musialby miec zapisany stan ktory stał się przed tym eventem, zeby było do czego cofać. Nie zajmowałoby to za dużo pamięci?

0

jak ogarnąć transakcje w aplikacjach opartych o chociażby Akke lub Vert.Xa ? A może ( i skłaniam się bardziej do tej wersji) - po prostu zła architektura i stos technologiczny skoro potrzebujemy transakcji ?

Ale transakcje w czym ? w neo4j transkacją zarządza server, robisz tylko HTTP request z zapytaniami - i to jest Twoja blokująca operacją którą masz zarządząć (w akka IO obsługuje się "specjalnie"), a robiąc zapytanie do cassandry, hmm, jakie transakcje (ironicznie oczywiście, bo posiada takowe "lekkie" transakcje) ?
Ty się nie martw o transakcje ale o blokującą operacje, bo jaka jest różnica ? Co jest specjalnego w tych transakcjach ?

Do rzeczy - jak w aplikacjach opartych o rozwiązania "message driven" i różnych async frameworkach zapewnić spójność danych w razie failu ? 

Jeżeli tobie chodzi o systemy rozproszone budowane używajc np: akki czy vert.x to zakładasz że masz eventual consistency

EDIT

W Springu sprawa jest nadzwyczaj prosta - @Transactional lub programowo odpalamy transakcje. W modelu jednowątkowym wszystko jest proste

Jedyny problem jaki widzę to że transakcje w takich cudach jak spring są wrzucane w ThreadLocal (w EJB to na bank ) - także to jest jedyna rzecz o której trzeba pamiętać, ale nie wyobrażam sobie przepychania jednej transakcji przez 3 wątki DD:D

0

Ja również niezbyt to widzę ;)

A jednak :D tylko zamiast przepychać transakcje, przepycha się ... logi :D thx LOGBACK :D

Zatem pytanie moje brzmi - jak ogarnąć transakcje w aplikacjach opartych o chociażby Akke lub Vert.Xa ? A może ( i skłaniam się bardziej do tej wersji) - po prostu zła architektura i stos technologiczny skoro potrzebujemy transakcji ?

Pamiętaj jednak że np: Netty, Akka**(based on netty)** czy vert.x**(based on netty)** mają dość prosty memorry model :D wszystko w jednym wątku - a przynajmniej wszystkie nieblokujące operacje, czyli np: mając jakiś server napisany na netty, pochód po wątkach będzie wyglądał mniej wiecej tak

request -> ( czytanie bajtów wątek A ) -> (komponowanie to w HTTP request wątek A) -> (tutaj możesz to przeorać na jakiś Twój DTO, tez na wątku A) -> (tutaj możesz wrzucić dane do bazy, zakładając jakiegoś brzydkiego blokującego JDBC odpalisz to w jednym wątku ale innym niż A - żeby nie blokować głównego - czyli np: wątek B)

jedyna różnica jaką będziesz miał między springowym @Transakszonal to że sam będzie musiał to jakoś obsłużyć (skołować entityManager i odplamić commita samodzielnie) - nie ma magii :)

nie wiem co Ty się tak boisz tych transakcji :)

0

Właściwie nie samych transakcji - wychodzi praktycznie zerowa znajomość ES. Bardziej chodzi mi o utrzymanie świata bez wadliwych danych ;)

0

Bardziej chodzi mi o utrzymanie świata bez wadliwych danych

Coś za coś. Jak masz monolita (nie hejtuje - to chyba nie jest pejoratywne określenie D:D ) który uderza to jednego servera na którym stoi jakiś postgress to spoko, możesz zapewnić izolacje podczas zapisu do bazy, jakąś kolejność, zablokować pisanie do tabeli czy coś - tylko to się nie scaluje. Jak masz 10instancji jednego serwisu które randomowo strzelają do 10nodów cassandry to .. to masz problem :D Oczywiście da się to utrzymać i zapewnić spujność (ale trzeba być świadomym że ACID to bajka w takim środowisku, że exactly-once-delivery to tylko w bullshit ), allegro teraz staje się message-driven (e.g. https://github.com/allegro/hermes) i żyją, obsługują transakcje finansowe - jakoś działa :)

ES

co to jest ?

0

Akurat właśnie zaczynam wychodzić po malutku spod płaszczyka Springa, JPA i kilku innych technologii i poprzez Vert.X'a chcę dojść do Scali i Akki. Mam już dość patrzenia na kod, w którym wstrzykuje się beana z samymi staticami... Doceniam obecne technologie i są super. Jednak niektórzy kodzą "na pałę" i powtarzają te same schematy od X lat - często - te same błędy.

0

Vert.X'a chcę dojść do Scali i Akki

hmm, ciekawa koncepcja :) też kiedyś miałem takie myślowe grafy że naucze się tego potem tamtego i na końcu tego co naprawdę chciałem :D
Chcesz pisać w scali to pisz od razu - nie ucz się Vert.X'a tylko po to żeby "zrozumieć asynchroniczność" (domyślam się że taki jest powód).

Nie musisz się od razu tak radykalizować :) może http-akka ? albo jak nie chcesz uciekać z javy to rxNetty (https://github.com/ReactiveX/RxNetty) ?
Albo wgl najpierw możesz pobawić się właśnie netty :) wszystkie "trendii" frejmłorki czy to w scali (finatra) czy w javie(rest-express), albo klienci (datastax(tutaj driver chyba na tym stoi :) ), neo4j)

niektórzy kodzą "na pałę" i powtarzają te same schematy od X lat - często - te same błędy.

Musisz szukać pracy gdzie są ludzie po dobrych studiach ;D

0

Nie bardzo rozumiem, co model obsługi współbieżności ma do transakcji.
Generalnie w obu przypadkach masz te same problemy. O np. taki (pseudokod):

doStuffSynchronously1()
doStuffSynchronously2()   // jak to się zepsuje to jak wycofasz operację 1?
future1 = doStuffAsynchronously1()
future2 = doStuffAsynchronously2()
waitForAll(future1, future2)

Jeżeli chcesz wykonać dwie operacje na różnych zasobach w jednej transakcji, to serwisy kontrolujące te zasoby muszą umieć obsługiwać jakiś protokół zarządzania transakcjami. Czy będzie to 2PC, 3PC, RAFT czy Paxos czy może oba zasoby są na jednej maszynie i wystarczy zcentralizowany monitor transakcji z dziennikiem i blokadami - to już jest zupełnie ortogonalne do tego, czy komunikaty przesyłasz synchronicznie czy asynchronicznie.

Jako ciekawostkę mogę dodać, że pracuję teraz nad systemem gdzie wszystko jest asynchroniczne (oparte na Netty), a pewne funkcje są realizowane właśnie transakcyjnie przy pomocy rozproszonego dziennika zdarzeń i rozproszonych blokad realizowanych na bazie algorytmu Paxos.

0

Może da się jakoś oddelegować menadżer transakcji na zewnątrz, w typowym serwerze aplikacyjnym jest on zawsze obecny i implementuje właśnie protokół 2PC

0

Nie wiem jaki powód kierują Tobą, aby poznawać Vert.x oraz akkę. Jeśli nie jest to tylko asynchroniczność, ale też architektura mikorserwisów oraz reaktywna architektura to zapomnij o transakcjach. Lepiej skup się na chwilowej niespójności danych (eventually consistent) i operacjach blokujących. Procesy biznesowe nie potrzebują transakcji (to nie moje stwierdzenie, ale raczej się z nim zgadzam).
Przykładowo tworząc jakieś rozwiązanie w vert.x masz Verticle, które mogą odpowiadać pojedynczemu mikroserwisowi, a każdy mikroserwis przechowuje tylko swój stan i jeśli do tego potrzebuje bazy danych to ma on swoją dedykowaną bazę danych. Nie zalecane jest, aby wiele mikroserwisów miało dostęp do jednej bazy danych. Oczywiście wewnątrz pojedynczego serwisu możesz mieć transakcje.
Przy tych technologiach raczej zadałbym takie pytanie: jeden mikroserwisy (lub request) wywołuje jakieś akcje na dwóch innych mikroserwisach, co się stanie jeśli w jednym z mikroserwisów będzie np. jakiś błąd (załóżmy że odpowie błędem)?
Jeśli chcesz coś więcej poczytać o mikroserwisach to wejdź na blog Martina Fowlera, a jeśli to będzie za mało to polecam książkę "Building microservices" (chyba taki był tytuł).

1 użytkowników online, w tym zalogowanych: 0, gości: 1