© DrHitch/Shutterstock.com
Von Monolithen und Microservices

3 Lost in Transaction: Businesstransaktionen mit Microservices umsetzen


Die Auftrennung des historisch gewachsenen Monolithen in eine Unmenge von Microservices scheint heute Pflicht. Wirklich unabhängig sind die Services am Ende allerdings nur dann, wenn die Trennung konsequent auf allen Ebenen vollzogen wird. Nicht nur den Code, sondern auch die Datenbank gilt es zu trennen. Willkommen in der Wunderwelt der verteilten Transaktionen.

Die Vorteile Microservices-basierter Architekturen sind hinlänglich bekannt. Ist erst einmal ein passender Schnitt gefunden – Domain-driven Design lässt grüßen –, können die einzelnen Services mehr oder minder unabhängig voneinander entwickelt, getestet und deployt werden. Dies erhöht die Agilität der Teams und vermindert die Umsetzungsdauer neuer Features (a.k.a. Time to Market).

Eine wesentliche Grundvoraussetzung für den Erfolg einer Microservices-basierten Architektur ist dabei die konsequente Trennung der Services und ihrer Ressourcen. Getreu dem Motto „share nothing“ wird nicht nur der Sourcecode voneinander getrennt, sondern auch die zugehörige Datenhaltung. Nur wenn auch dieser Schritt konsequent gegangen wird, kann tatsächlich von einer losen Kopplung und einer damit einhergehenden Unabhängigkeit der Services gesprochen werden.

Was ist nun aber, wenn sich ein Use Case über mehrere Services und somit auch über mehrere Datenquellen aufspannt? Nehmen wir als Beispiel eine stark vereinfachte Variante eines Check-out-Prozesses innerhalb eines Webshops. Im Rahmen des Check-outs, also des Verkaufs von Produkten an einen Kunden, wird die Anzahl der Produkte innerhalb des Lagersystems um die gekaufte Menge reduziert. In einem monolithischen System würde dies transaktional erfolgen. In einem Microservices-basierten System dagegen würde es wahrscheinlich einen Check-out Service und einen Inventory Service inkl. eigener Datenhaltung geben. Durch die Auftrennung der Datenhaltung und damit auch der Datenbank ist die Umsetzung der benötigten Transaktion nicht so ohne Weiteres realisierbar. Wir brauchen einen Plan B.

Versuch 1: Transaktionen vermeiden

Die aus technologischer Sicht einfachste Variante, mit dem eben beschriebenen Problem umzugehen, ist, die Services so zu schneiden, dass sich Transaktionen grundsätzlich nur innerhalb eines Service abspielen. Was sich in der Theorie denkbar einfach anhört, hat in der Praxis enorme Konsequenzen. Zwar vermeiden wir durch den Ansatz die Notwendigkeit des Aufteilens einer Transaktion auf mehrere Services, sorgen aber auf der anderen Seite für unnatürliche Service-Grenzen.

Nehmen wir noch einmal das Beispiel von oben. Um die notwendige Transaktion zu realisieren, müssten wir die beiden Services Checkout und Inventory zu einem CheckoutAndInventory Service zusammenlegen. Die erhofften Vorteile der Microservices-basierten Architektur gingen so verloren. Wir enden aus fachlicher Sicht in einem zu großen Service. Der Service hätte durch den Wegfall von Seperation of Concerns und Single Responsibility mehr als nur einen fachlichen Verantwortlichen und würde wahrscheinlich eine Größe einnehmen, die nicht mehr von nur einem agilen Team gemanagt werden kann.

Natürlich könnte man ggf. auch noch einmal die Grenzen der Services prüfen und den fachlichen Schnitt derart verschieben, dass zwar die notwendige Transaktion Teil eines der beiden Services wird, ansonsten aber weiterhin zwei Services bestehen bleiben. Dies ist dann eine Option, wenn die Services eher auf Entitäten aufbauen als auf Use Cases und somit von Anfang an ein ungünstiger Service-Schnitt gewählt wurde. In unserem Fall stellt das nicht wirklich eine Option dar. Was also tun?

Your Coffee Shop Doesn’t Use Two-Phase Commit

Als Erstes sollten wir uns einmal die Frage stellen, ob wir denn tatsächlich eine Transaktion benötigen. Was für eine dumme Frage, wird sich jetzt sicherlich der eine oder andere Leser denken. Natürlich brauchen wir eine Transaktion. Schließlich finden schreibende Zugriffe auf zwei Tabellen statt. Und wenn es eins zu vermeiden gilt, dann ist das doch wohl ein inkonsistenter Zustand in unserer Datenbank! Aus technologischer Sicht ist diese Aussage sicherlich korrekt. Aber stimmt sie auch aus fachlicher Sicht? Ist die Welt tatsächlich so transaktional, wie wir sie in unseren Systemen immer darstellen? Zu dieser Frage hat sich bereits vor fünfzehn Jahren Gregor Hohpe Gedanken gemacht und in seinem Artikel „Your...

Neugierig geworden?

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang