Transakcje między aplikacjami

0

Cześć,

Mamy w firmie taki problem. W dwóch metodach, następuje zapis do dwóch schematów w tej samej bazie danych i wyglądać ma to tak, że jeśli coś się nie powiedzie w jednym lub w drugim zapisie, wszystko ma być zrollbackowane, jednym słowem - dwa zapisy mają być w jednej transakcji. Problem jest w tym, że zapis do drugiego schematu chcemy zrobić przez wystawione przez nas wewnętrzne API, żeby nie duplikować encji i repozytoriów w jednym projekcie i pojawia się pytanie - czy Spring "ogarnie" transakcyjność poprzez dwie aplikacje? A jak nie, to w jaki sposób możemy to rozwiązać?

4

czy Spring "ogarnie" transakcyjność poprzez dwie aplikacje

xD To nie może być pytanie na serio. Już 1 kwietnia jest?

żeby nie duplikować encji i repozytoriów w jednym projekcie

ever heard of them modules? Wiesz że da się zrobić małego jara który trzyma tylko kawałek projektu? Nie trzeba wtedy niczego duplikować. Magia! Szczególnie przydatne właśnie na jakieś takie DTOsy.

Ale tak generalnie to macie raczej zrypany design. Bo co jak ten serwis np. będzie miał lagi bo za duża kolejka requestów do przetworzenia? Zapewnienie czeogś takiego jak transakcja pomiędzy aplikacjami to jest ciężka sprawa i sugerowałbym nie iść tą droga.

0

ever heard of them modules? Wiesz że da się zrobić małego jara który trzyma tylko kawałek projektu? Nie trzeba wtedy niczego duplikować. Magia! Szczególnie przydatne właśnie na jakieś takie DTOsy

Można by było tak zrobić, ale nie są to DTOsy, które będą współdzielone, tylko encje bazodanowe (JPA), chyba że da się tak zrobić, że jedną encję (jako klasę w javie) zdefiniować dla dwóch schematów bazy danych.

1

A co to niby są klasy @Entity jak nie DTO? :D I przecież taka klasa wcale nie wie do jakiego schematu chcesz ją aplikować...
Ja bym osobiście zaczął od wywalenia JPA i połowa problemów sama zniknie. Potem przeniósłbym tą transakcyjną logikę do osobnego serwisu (całą, nie tylko jej kawałek) i znów problem sam znika.

2

Jeśli zmiany będą realizowane na osobnych połączeniach bazodanowych, to siłą rzeczy będą to osobne transakcje. Schemat nie ma nic do rzeczy jeśli chodzi o transakcje. Pozwala lepiej organizować obiekty bazodanowe i zarządzać nimi.

Transakcje bazodanowe mogą ułatwić rozwiązywanie, ale nie rozwiązują automagicznie problemów biznesowych.

Istnieją transaction managery i protokół dwu-fazowego zatwierdzania transakcji, ale na tym levelu nie pchałbym się w takie rozwiązanie.

Powinieneś raczej zaprojektować odpowiednią logikę biznesową (z akcjami kompensacyjnymi dla transakcji bazodanowych, które zostały zatwierdzone, ale później we flow coś poszło nie tak i trzeba kompensować poprzednie akcje), a nie liczyć, że Spring coś Ci rozwiąże.

1

Podałeś konkrety w końcu w komentarzach pod poprzednim postem.
Jak najbardziej da się to zrobić generczynie i się robi - two phase commit i EJB ( ͡° ͜ʖ ͡°) (ewentualnie troche mniej -> gołe JTA, distributed transactions). (nie Spring, spring tu nie pomoże (raczej).
To że się da, nie znaczy, że należy- two phase commit to bagno i chyba wszystkie firmy, które się w to bawiły (z EJB, czy bez) mają to teraz na liście technologii zakazanych.

Zwykle da się przemyśleć tak logikę aplikacji, żeby 2pc nie był potrzebny. Jest to komplikacja, ale w ostatecznych rachunku raczej mniejsza niż utrzymywanie infrastruktury EJB czy podobnej.

0

Moglibyście doradzić, co jest najlepszym rozwiązaniem w takiej sytuacji? Rozwiązanie które zaproponował @Shalom (czyli z dziedziczeniem w JPA) jest chyba w porządku, ale wtedy będziemy mieli 2x budowanie encji (dla każdego schematu) i 2x wywołanie .save() z repo. Od two-phase commit też raczej chciałbym uciec, nie chcę zagrzebać się w bagno. Jest może jakieś lepsze rozwiązanie na to?

1

Jedne dobre rozwiązanie to wyciągnięcie tej logiki do jednego miejsca i zrobienie normalnej transakcji bazodanowej w tym jednym miejscu. Póki co dla ciebie problem stanowi jakiś zupełnie nieistniejący problem z serii "mam operacje na dwóch schematach bazy". To jest problem z gównianym pomysłem na użycie JPA, a nie problem "logiczny". Zrób tam normalne query do bazy danych i zamkniejsz się w 5 linijkach kodu, bez mapowania miliona klas i czarowania z dziedziczeniem w JPA.
Bo teraz to uprawiasz taką dzielną walkę z problemami nieznanymi w innych rozwiązaniach. Ja wiem ze jak masz młotek to wszystko wygląda jak gwoździe, ale zlituj się.

Zresztą mamy tu książkowy przykład na http://xyproblem.info/ bo próbujesz się dowiedzieć jak zrealizować błędny pomysł, zamiast wyjść od pytania jak rozwiązać wyjściowy problem.

Wyjściowy problem wydaje się trywialny, a tu już powoli wchodzi EJB, rozproszone transakcje, dziedziczenie w JPA, two-phase-commit...

1

Ja bym w ogóle testowo zaczął od zdropowania tych baz danych. Pewnie i tak niepotrzebne,

3

Czas potrzebny na wymyślenie, a potem utrzymanie tego potworka (2PC) poświęciłbym raczej na rozkmince, w jaki sposób kompensować ew. rozjazdy. Za chwilę dostaniecie wymaganie, żeby calle HTTP były transakcyjne. To jakaś fikcja architektoniczna.

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