Version 4 · Migration
Transaktionen, JTA, JMS und Datenbank
Globale Containertransaktionen werden analysiert, abgesichert und schrittweise durch klare lokale Transaktionen, Outbox und idempotente Consumer ersetzt.
Warum Transaktionen der harte Kern sind
Viele WebSphere-Systeme nutzen JTA/XA über Datenbank, JMS und manchmal SOAP-Folgeaufrufe. Das ist im Monolith bequem, wird aber in verteilten Containerlandschaften teuer und störanfällig. Deshalb wird nicht blind XA nachgebaut, sondern die fachliche Konsistenz neu modelliert.
Zwischenzustand: explizite Transaktion plus Outbox
Transaktionsschnitt mit markiertem Outbox Pattern
public class InvoiceApplicationService {
// Pattern: Transaction Script als Zwischenzustand, danach schrittweise zu Domain Model.
@Transactional
public InvoiceResult create(CreateInvoiceCommand command) {
Invoice invoice = useCase.handle(command);
// Pattern: Transactional Outbox - Event wird in derselben DB-Transaktion vorgemerkt.
outbox.store(OutboxMessage.from(invoice.createdEvent()));
return InvoiceResult.ok(invoice.number(), invoice.total());
}
}
Migrationsentscheidung
| Fall | Empfohlene Richtung |
|---|---|
| Eine DB, ein Service | Lokale Transaktion genügt meistens. |
| DB + Event | Transactional Outbox statt direktem Senden in derselben Methode. |
| DB + MQ mit exakt-einmal Wunsch | Idempotenz, Inbox/Outbox, fachlicher Dedupe-Key. |
| Mehrere Services | Saga / Process Manager statt globaler JTA über Servicegrenzen. |
| Stored Procedure als Regelkern | Golden Master Tests, dann Regel extrahieren oder bewusst kapseln. |
Fehlerbilder
| Fehler | Gegenmaßnahme |
|---|---|
| Doppelte Nachricht | Consumer idempotent machen, Nachrichtenschlüssel speichern. |
| Commit erfolgreich, Event fehlt | Outbox-Relay mit Wiederholung und Monitoring. |
| Event gesendet, DB rollback | Event erst nach Commit aus Outbox veröffentlichen. |
| Langlaufende Sperren | Transaktionsumfang verkleinern, Batch-Schnitt prüfen. |