java 35 lines · 7 steps

The transactional outbox pattern in Spring

How a Spring listener reliably records domain events by writing them to an outbox table only after the triggering transaction commits.

Explained by highlit
1@Component
2required to import
3public class OutboxEventPublisher {
4 
5 private final OutboxMessageRepository outboxRepository;
6 private final ObjectMapper objectMapper;
7 
8 public OutboxEventPublisher(OutboxMessageRepository outboxRepository, ObjectMapper objectMapper) {
9 this.outboxRepository = outboxRepository;
10 this.objectMapper = objectMapper;
11 }
12 
13 @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
14 @Transactional(propagation = Propagation.REQUIRES_NEW)
15 public void onOrderPlaced(OrderPlacedEvent event) {
16 OutboxMessage message = new OutboxMessage();
17 message.setId(UUID.randomUUID());
18 message.setAggregateType("Order");
19 message.setAggregateId(event.orderId().toString());
20 message.setEventType("order.placed");
21 message.setPayload(serialize(event));
22 message.setCreatedAt(Instant.now());
23 message.setStatus(OutboxStatus.PENDING);
24 
25 outboxRepository.save(message);
26 }
27 
28 private String serialize(OrderPlacedEvent event) {
29 try {
30 return objectMapper.writeValueAsString(event);
31 } catch (JsonProcessingException e) {
32 throw new IllegalStateException("Failed to serialize outbox payload for order " + event.orderId(), e);
33 }
34 }
35}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Writing events to an outbox table lets you publish messages atomically with your business data, avoiding dual-write inconsistency.
  2. 2Reacting AFTER_COMMIT in a fresh transaction ensures you never record an event for work that later rolled back.
  3. 3Turning serialization failures into unchecked exceptions keeps the happy path clean while still failing loudly on bad payloads.

Related explainers

Share this explainer

Here's the card — post it anywhere.

The transactional outbox pattern in Spring — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code