Spring: Transaktionskosten im Auge behalten

Das automatische Transaktionsmanagement ist nur eine der Spezialitäten des Spring Frameworks. So lässt sich transaktionales Verhalten einfach per @Transactional-Annotation auf Klassen- oder Methodenebene konfigurieren. Allerdings sollte man nicht zu großzügig beim Annotieren sein.

In herkömmlichen Schichten-Architekturen (Domäne / Datenzugriffsschicht / Serviceschicht / Controllerschicht / Viewschicht) werden Transaktionen in der Regel in der Serviceschicht konfiguriert. Und oft genug sind alle Methoden eines Service transaktional, sodass die Annotation @Transactional auf Klassen- bzw. hier Interfaceebene vollkommen ausreicht.

Etwas anders sieht die Sache mit Catapult und einem konsequent domänengetriebenen Entwurf aus: sämtliche Anwendungslogik gehört in die Modellklassen der Domäne, also auch alle transaktionalen Methoden. Ein unbedachtes Setzen der @Transactional-Annotation an die Modellklassen kann hier jedoch fatale Folgen haben. Jeder Zugriff auf ein einzelnes Domänenproperty über einen Getter wird in diesem Fall in einer eigenen Transaktion ausgeführt, kontaktiert also die Datenbank und führt damit unweigerlich zu erheblichen Performanceeinbußen auf datenintensiven Seiten. Richtiger und performanter ist ein gezieltes Annotieren nur genau der Methoden, die sich transaktional verhalten sollen.

Was uns hier Catapult vor Augen führt: Ein konsequent domänengetriebener Entwurf erfordert ein durchdachtes Architekturdesign, kann so jedoch Fehler aufzeigen, die bei der Aufteilung in die oben genannten Schichten leicht übersehen werden (weil sie dort zugegebenermaßen weniger fatale Folgen haben).

2 Antworten auf „Spring: Transaktionskosten im Auge behalten“
  1. FFD sagt am 15. Juni 2009 um 12:08 PM:
    Was ist denn die Motivation für so eine fein-granulare Transaktionssteuerung? Bei einer Web-Anwendung wie etwas Projektwerk müßte es doch völlig ausreichen, automatisch jeden Request in eine Transaktion zu packen. Bei 1000MIKES ist auch fast die komplette Web-Anwendung so gemacht, nur die Audio-Server haben eine Transaktionssteuerung auf Service-Ebene und das JSON-RPC-Polling ist ausgenommen (solange der Cache greift). Warum sollte man dann so eine feine Steuerung machen? Die Nachteile hast du ja durchaus beschrieben, aber was sind die Vorteile, wenn man nicht gerade gezwungen ist (wie bei den Cloud-Datenbanken, die keine globalen Transaktionen unterstützen)?
  2. Oliver Becker sagt am 16. Juni 2009 um 12:29 PM:
    Tatsächlich war das nach Erkennen des Engpasses spontan auch meine erste Idee. :-) Anstatt sich intensive Gedanken um das richtige Transaktionsmanagement machen zu müssen, erscheint es doch viel einfacher, für jeden Request automatisch eine gemeinsame Transaktion zu öffnen. Bei genauerer Betrachtung sieht man jedoch, dass einem dann die Möglichkeiten genommen werden, für einzelne Methoden gezielt Transaktionsparameter (etwa das Isolation-Level) einzustellen - oder Methoden sogar ganz ohne Transaktion auszuführen. Letzteres vermeidet unerwünschte Nebeneffekte, da sich Änderungen an persistenten Daten innerhalb einer (ReadWrite)-Transaktion automatisch in Datenbank-Updates niederschlagen, auch wenn dies gar nicht beabsichtigt war (ein Effekt, der mir übrigens schon einige Male Ärger bereitet hat). Meiner Erfahrung nach kommt man früher oder später um ein gezieltes Konfigurieren nicht herum.

Kommentare zu diesem Eintrag sind geschlossen.

Oliver Becker

04. Juni 2009
2 Kommentare

Tags: , , ,

Verwandte Artikel