Podczas projektowania interakcji między mikroserwisami często pojawia się pytanie o realizację rozproszonych transakcji. W monolitach wystarcza kontrola wbudowanych mechanizmów, ale w mikroserwisach sytuacja komplikuje się z powodu różnych baz danych, technologii i formatów wymiany danych. Główna zasada — unikać długich rozproszonych transakcji, ponieważ są one źle skalowalne i niosą ryzyko degradacji wydajności.
Zamiast klasycznych protokołów ACID zaleca się stosowanie wzorca SAGA. To łańcuch lokalnych transakcji, w którym każda mikrousługa rejestruje swoje zmiany i w razie potrzeby wykonania wycofania, wysyła operację kompensacyjną w ramach swojej odpowiedzialności.
Przykład uproszczonej realizacji zarządzania sagą w Node.js z REST:
// Orkiestrator Sagi w Express app.post('/saga', async (req, res) => { try { await serviceA.transaction(); await serviceB.transaction(); res.send('ok'); } catch (err) { await serviceA.rollback(); res.status(500).send('wycofanie wykonane'); } });
Kluczowe cechy:
Czy można używać klasycznych dwufazowych commitów (2PC) między mikroserwisami dla wsparcia transakcji?
Można, ale nie jest to zalecane dla architektur mikroserwisowych. 2PC spowalnia skalowanie i wiąże usługi technicznie oraz organizacyjnie.
Czy wszystkie scenariusze SAGA nadają się do operacji finansowych?
Nie. SAGA jest trudniejsza do prawidłowego zaimplementowania dla scenariuszy, w których istotne jest przestrzeganie zasad ACID, na przykład, przeliczenie sald na jednym koncie. Ważne jest tu ocenianie ryzyk i wybór kompromisu.
Jak odbywa się obsługa niepowodzenia kroków pośrednich, jeśli mikroserwis nie może się cofnąć?
W takich przypadkach należy wdrożyć ręczny lub zautomatyzowany protokół kompensacji, możliwe, że z pomocą oddzielnego dziennika zdarzeń.