ForgeNEX

Patrón transactional outbox en arquitecturas de empresa

Evita escritura dual entre base de datos y broker con una outbox transaccional, CDC, consumidores idempotentes y controles de orden, retención y monitorización.

2 min de lectura

En este artículo

El problema: guardar el estado y publicar el evento

Un servicio puede actualizar su base de datos y publicar después un mensaje. Si el proceso falla entre ambas acciones, el estado persistido y los consumidores quedan desalineados. Publicar primero tampoco resuelve la atomicidad: el evento puede anunciar un cambio que nunca se confirmó en la base de datos.

El patrón transactional outbox escribe el cambio de negocio y un registro de evento en la misma transacción local. Un componente posterior lee esa tabla y publica el evento en el broker. Así se evita depender de una transacción distribuida entre la base de datos y el sistema de mensajería.

Flujo y contrato del evento

  1. La aplicación valida la operación.
  2. En una misma transacción, persiste el estado de negocio y la fila de outbox.
  3. Un publicador o mecanismo CDC detecta la fila y emite el mensaje.
  4. El consumidor valida el contrato, procesa el mensaje y registra su resultado.
  5. La outbox se retiene y limpia según una política que permita operar, investigar y recuperar el flujo.

Define un ID de evento único, tipo, versión de esquema, fecha, clave de agregado y payload mínimo. Evita incluir datos personales o secretos que el consumidor no necesita. Para conservar orden por agregado, decide cómo se asignará la clave y cómo tratarás reintentos.

Diseña para duplicados y fallos

La entrega puede repetirse, por ejemplo si el publicador envía el mensaje y falla antes de marcarlo como procesado. Por eso el consumidor debe ser idempotente: registrar el ID tratado, rechazar efectos duplicados o aplicar una operación segura ante repetición.

Define comportamiento para mensajes inválidos, retrasos, reintentos, cola de errores, reinicio del conector y retención del log de cambios. Supervisa antigüedad de la fila más antigua, retraso de publicación, errores y volumen de duplicados. La outbox no garantiza por sí sola “exactamente una vez” en todo el recorrido.

Cuándo encaja y qué probar

El patrón es útil cuando una operación debe guardar estado y notificar a otros servicios sin perder la relación entre ambos. Añade una tabla y un flujo operativo, así que comprueba si la complejidad se justifica frente a una integración síncrona más sencilla.

Prueba caída de la base de datos, indisponibilidad del broker, caída del conector, repetición de eventos, orden, carga sostenida y recuperación desde el último punto confirmado. Conserva trazabilidad entre la petición original, fila de outbox, mensaje publicado y resultado del consumidor.

Debezium describe su Event Router como una forma de capturar cambios de una tabla outbox y transformarlos en mensajes. El diseño de tablas, la entrega y las garantías deben verificarse para las versiones y conectores concretos.

Complementa la guía de idempotencia en APIs y webhooks y el artículo sobre arquitecturas event-driven con Kafka y Debezium.

Referencias

Sigue leyendo