Ablauf
POST /api/orders/{id}/accept
|
v
AcceptOrderUseCase
|
+--> OrderRepository.save(order)
|
+--> OutboxPublisher.append(OrderAccepted)
|
v
PostgreSQL Transaction
|
v
OutboxRelayJob pollt NEW Events
|
v
RabbitOrderEventPublisher
|
v
RabbitMQ exchange order.events
|
v
Queue billing.order-accepted
|
v
BillingOrderAcceptedConsumer
Warum Outbox?
Ohne Outbox entsteht ein klassisches Dual-Write-Problem:
- Bestellung wird in DB gespeichert.
- Event soll an RabbitMQ gesendet werden.
- Zwischen DB Commit und RabbitMQ Publish kann die Anwendung abstürzen.
Die Outbox löst das Problem, indem das Event zuerst in derselben Datenbanktransaktion gespeichert wird. Ein separater Relay-Job veröffentlicht später zuverlässig.