Transaktionen & Konsistenz: Local, JTA, Saga, Outbox

Enterprise-Systeme scheitern häufig nicht am Code, sondern an falschen Konsistenzannahmen.

JTAOutboxSagaIdempotenz
Saga und Transactional Outbox Ablauf
Saga und Transactional Outbox Ablauf

Transaktionsarten

ArtBeispielGrenze
Lokale DB-TransaktionOrder + Outbox in einer DBNur eine Datenbank
JTA/XADB + JMS in einer globalen TXKomplex, teuer, nicht überall cloud-nativ
SagaOrder, Billing, Inventory separatEventually consistent
OutboxDB-Commit und spätere Event-PublikationRelay und Idempotenz nötig

Outbox

Outbox speichert ein Event in derselben Transaktion wie den fachlichen Zustand. Ein separater Prozess veröffentlicht später zuverlässig.

Outbox Relay
public interface OutboxPort { // Pattern: Transactional Outbox Port
    void append(DomainEvent event);
    void appendAll(List<DomainEvent> events);
}

public final class OutboxRelay { // Pattern: Polling Publisher
    private final OutboxStore store;
    private final MessagePublisher publisher;

    public void publishPending() {
        for (OutboxMessage msg : store.lockNextBatch(100)) {
            publisher.publish(msg.topic(), msg.payload(), msg.idempotencyKey());
            store.markPublished(msg.id());
        }
    }
}

Saga

Eine Saga koordiniert mehrere lokale Transaktionen. Bei Fehlern wird nicht zurückgerollt wie in einer DB, sondern kompensiert.

Idempotenz

Jeder Consumer muss Mehrfachzustellung aushalten. Dafür braucht man Idempotency Keys, deduplizierende Tabellen oder fachliche natürliche Schlüssel.

Code

Saga mit Kompensation
public final class OrderSaga { // Pattern: Saga Orchestrator
    public void on(OrderPlaced event) {
        try {
            billing.reserveInvoice(event.orderId());
            inventory.commitReservation(event.orderId());
        } catch (BillingUnavailable ex) {
            inventory.releaseReservation(event.orderId()); // Kompensation
            orders.markPaymentPending(event.orderId());
        }
    }
}

Warnung

Nicht jede verteilte Fachlogik braucht sofort Saga. Häufig reicht zuerst ein klarer Outbox-Prozess mit idempotenten Consumern.
⌂ Cockpit