01/10/2021 - Transactional Outbox pattern with Debezium, Quarkus and Postgresql¶
The Transactional outbox pattern helps to save within the same database transaction, the event you want to publish to the messaging middleware, like Kafka. I just finalized an example of Order management microservice in the context of the Vaccine at scale demo.
The implementation uses Quarkus with Reactive Messaging, OpenAPI, JAXRS and theDebezium outbox pattern with Debezium change data capture for Postgresl to Kafka.
The main classes in this project is the OrderService.java class which use the following code approach. Get the Order entity persist it in the same transaction as 'emitting the event', which is not really emitting an event, but save to the orderevents
table.
@Inject
Event<ExportedEvent<?, ?>> event;
@Transactional
public VaccineOrderEntity saveNewOrder(VaccineOrderEntity orderEntity) {
orderEntity.status = OrderStatus.OPEN;
orderEntity.creationDate = simpleDateFormat.format(new Date());
orderRepository.persist(orderEntity);
event.fire(OrderCreatedEvent.of(orderEntity));
return orderEntity;
}
So the trick is coming from the OrderCreateEvent which is a io.debezium.outbox.quarkus.ExportedEvent.
The application is configured to specify what table to use, and what will be the key and value of the future Kafka records.
quarkus.debezium-outbox.id.name=aggregateid
quarkus.debezium-outbox.id.column-definition="DECIMAL NOT NULL"
quarkus.index-dependency.outbox.group-id=io.debezium
quarkus.debezium-outbox.aggregate-id.name=aggregateid
quarkus.debezium-outbox.aggregate-id.column-definition="DECIMAL NOT NULL"
quarkus.index-dependency.outbox.artifact-id=debezium-quarkus-outbox
quarkus.debezium-outbox.table-name=orderevents
The deployment of this service to Kubernetes is explained in this section. And for the Debezium Change data Capture component, as it is a Kafka Connector, I use the Strimzi source to image approach, as described here.
A new added Order
is now visible in the entity table
and the orderevents table.