# Saga Pattern ## Microservice Architektur Die Microservice Architektur wird heutzutage der Monolithischen Architektur oft vorgezogen. Auch wenn sie durchaus mit vielen Vorteilen kommt, führt sie auch neue Probleme ein, auf welche reagiert werden muss. Bei der Microservice Architektur wird eine Applikation so aufgeteilt, dass sie über mehrere kleinere Services bereitgestellt werden kann, welche miteinander die ganze Applikation repräsentieren. Bei dieser Vorgehensweise kommen jedoch neue Probleme auf: Wie soll mit Transaktionen umgegangen werden, die über mehrere Services laufen? Wie sollte mit Fehlern umgegangen werden? Das Saga Pattern versucht eine Lösung für diese Probleme zu schaffen. ## Verteilte Transaktionen Einer der Vorteile bei Microservices ist, dass für jeden Service ein eigener Stack gewählt werden kann. So können domänenspezifische Daten unabhängig von einander auf einem passenden Datenspeicher abgelegt werden, der am besten zu den Anforderrungen passt. Es kann jedoch sein, dass eine Transaktion über mehrere Services läuft. In diesem Fall muss dafür gesorgt werden, dass Datenkonsistenz weiterhin bestehen bleibt. Um dieses Problem besser zu verstehen, werden wir uns ein Beispiel anschauen. In unserem Beispiel haben wir einen Online Shop und die Transaktion einer Bestellung: ![[Transaktion Beispiel.svg]] Wir haben eine Reihe von Schritten die benötigt werden, um eine Bestellung aufzugeben. Da wir unseren Online Shop als Microservice Applikation bereitstellen, ist jeder dieser Schritte auf einem eigenen Service. Um also Datenkonsistenz über all diese Schritte zu garantieren, müssen alle Microservices ihre Transaktion erfolgreich beenden. Wenn ein Fehler auftritt, müssten alle vorherigen Services ihren Schritt rückgängig machen. ## Das Saga Pattern Das Saga Pattern ist ein Fehler Management Muster welches versucht, das Sicherstellen der Datenkonsistenz zu vereinfachen. Die Saga Architektur verwaltet eine Transaktionen durch eine Reihe von kleineren lokalen Transaktionen. Eine lokale Transaktion ist der Schritt der von einem Saga Teilnehmer, also einem Microservice, durchgeführt wird. Es zielt darauf ab, dass entweder alle Schritte problemlos durchlaufen, oder dass jede bereits durchgeführte lokale Transaktion wieder rückgängig gemacht wird. ### Der Saga Flow ![[Saga Flow.svg]] Bei jedem Schritt haben wir nun auch noch einen Schritt um diesen bei einem Fehler rückgängig zu machen. Dies ist möglich, da die einzelnen Schritte eben als lokale Transaktionen behandelt werden. Wenn also ein Schritt fehlschlägt, wird auf den alternativen Pfad (in rot) geleitet welcher alle nötigen Schritte durchführt, um die Transaktion rückgängig zu machen. Der Service informiert also über den Fehler und löst den Lösungsschritt aus. So kann sichergestellt werden, das die Datenkonsistenz in jedem Fall bewahrt bleibt. ## Arten von Sagas Grundsätzlich gibt es zwei mögliche Strategien um dieses Muster zu implementieren. ### Choreografie Bei einer Choreografie sind die Services selbst dafür zuständig die anderen Services über den Verlauf zu informieren. Jeder Microservice kenn seine eigene Aufgabe und den Kontext der Transaktion. Dies setzt jedoch voraus, dass die einzelnen Services sich koordinieren können um den Stand der Transaktion aufrecht zu halten, da es keine zentrale Einheit für dies gibt. Diese Strategie ist einfacher zu implementieren und dann vorteilhaft, wenn nicht viele Schritte für die Transaktion nötig sind und auf Features wie Tracing verzichtet werden kann. Bei zu vielen beteiligten Diensten wird diese Strategie jedoch sehr schwierig umzusetzen und zu unterhalten. ### Orchestrator Bei der Saga Implementation mit einem Orchestrator gibt es eine zentrale Einheit welche für die Steuerung der lokalen Transaktionen zuständig ist. Dieser Orchestrator ist also für die Koordinierung der Microservices und die Verwaltung des Transaktionsstatus zuständig. ![[Saga Orchestrator.svg]] Einer der grössten Vorteile ist, dass zwischen den einzelnen Services keine Abhängigkeit mehr existiert. Die Microservices müssen nicht mehr miteinander kommunizieren und stattdessen nicht mehr über den nächsten Schritt der Transaktion wissen. Stattdessen müssen sie ihren Status nur mit dem Orchestrator teilen welcher die Benachrichtigung des nächsten Services übernimmt. Ein Orchestrator ist dafür aber ein Single Point of Failure, was ein grosses Risiko darstellen kann. Wenn der Orchestrator ausfällt ist kein Schritt der Saga mehr lauffähig.