Featured image of post How to Implement the Outbox Pattern in a Simple Way

How to Implement the Outbox Pattern in a Simple Way

Learn how to implement the Outbox Pattern easily using Spring Boot and Spring Modulith with domain events

How to Implement the Outbox Pattern in a Simple Way!

If you are building a modular monolith using Spring Boot and Spring Modulith, implementing the Outbox Pattern can be very straightforward.

Spring Modulith allows you to guarantee message delivery by using domain events. You only need to annotate your event consumer with @TransactionalEventListener.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@Component
class OrderEventListener(
    private val notificationService: NotificationService
) {

    @TransactionalEventListener
    fun handleOrderCreated(event: OrderCreatedEvent) {
        notificationService.sendOrderConfirmation(event.orderId)
    }
}

Spring Modulith will automatically:

  • Create the event_publication table
  • Retry failed event deliveries
  • Ensure messages are eventually delivered

You don’t need to implement a custom outbox table or write retry logic yourself.

One Thing to Be Aware Of!

By default, event publishing and event listeners run synchronously in the same thread. This means the user request will wait until the listener finishes processing.

How to Improve This

You can make the listener run asynchronously by adding the @Async annotation. This allows the request to finish without waiting for the listener.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@Component
class OrderEventListener(
    private val notificationService: NotificationService
) {

    @Async
    @TransactionalEventListener
    fun handleOrderCreated(event: OrderCreatedEvent) {
        notificationService.sendOrderConfirmation(event.orderId)
    }
}

By default, @Async uses platform threads, which can be expensive. To improve performance and scalability, you can enable Java virtual threads:

1
spring.threads.virtual.enabled=true
Built with Hugo
Theme Stack designed by Jimmy