Ejercicio: construye un patrón Transactional Outbox en n8n
Ejercicio editorial práctico: construye un patrón transactional outbox en n8n para que un evento solo se marque entregado tras confirmarlo el sistema receptor.

Comprobado con las fuentes citadas el .
Ejercicio editorial: qué construirás y por qué
Este es un ejercicio editorial: una tarea de práctica autoguiada para realizar en tu propio entorno de n8n, no una tarea certificada ni un flujo de trabajo que hayamos construido y probado por ti. El objetivo es construir un patrón transactional outbox en n8n para que un evento enviado a un sistema receptor solo se marque como entregado después de que ese sistema confirme realmente su recepción, y no en el momento en que tu flujo de trabajo lo dispara.
Trabajarás con una base de datos Postgres y un destino receptor, ya sea un endpoint HTTP o un broker de mensajes, escribirás un registro de negocio y un registro de outbox a la vez, y luego construirás un pequeño relé en n8n que detecte las nuevas filas de outbox, las envíe y marque cada fila como procesada solo después de recibir confirmación.
Contexto: el problema de la doble escritura y qué garantiza el patrón transactional outbox
El problema que aborda este patrón se conoce como el problema de la doble escritura. Un flujo de trabajo necesita actualizar una base de datos y notificar a un sistema receptor sobre ese cambio, pero son dos operaciones separadas; sin una transacción distribuida, una puede tener éxito mientras la otra falla, dejando a ambas desincronizadas. El patrón transactional outbox evita esto escribiendo el registro de negocio y un registro del evento a enviar, la fila de outbox, dentro de la misma transacción de base de datos, de modo que ambos nunca puedan divergir por sí solos.
Vale la pena ser precisos sobre lo que esto realmente garantiza. La propia guía de n8n sobre el patrón afirma claramente que la entrega duplicada siempre es posible, así que lo que en realidad estás construyendo es una entrega confiable, confirmada al menos una vez, no una entrega literalmente exactamente una vez. Por eso el patrón solo funciona de forma segura junto a un consumidor idempotente en el otro extremo, uno que pueda recibir el mismo evento dos veces sin actuar dos veces sobre él.
El arquitecto de software Chris Richardson señala lo mismo en su propia descripción del patrón, al escribir sobre el lado consumidor de este intercambio.
La guía de n8n también da una regla de funcionamiento simple para el propio flujo de trabajo: marcar una fila de outbox como procesada solo una vez que la entrega realmente se haya logrado, nunca antes. Esa regla es en torno a la cual se estructuran los pasos de construcción de más abajo.
Sources: Pattern: Transactional outbox, How the Transactional Outbox Pattern Guarantees Event Delivery – n8n Blog
Requisitos previos y datos de entrada
Antes de empezar, comprueba que tu configuración coincide con lo que este ejercicio asume. Está escrito para un desarrollador que ya se siente cómodo con el nodo Postgres de n8n y con el manejo básico de errores, no como un primer flujo de trabajo.
Los datos de entrada concretos son una tabla de negocio que ya tengas o que crees para este ejercicio, como una tabla de pedidos, una nueva tabla de outbox con columnas para un payload, un indicador de estado y una marca de tiempo, y las credenciales que n8n necesita para acceder tanto a Postgres como a tu destino receptor elegido.
Sources: Postgres | Nodes | n8n Docs, HTTP Request | Nodes | n8n Docs, RabbitMQ | Nodes | n8n Docs
Restricciones
Algunas restricciones determinan cómo construyes esto, y se derivan directamente de cómo se comportan los nodos relevantes de n8n, más que de buenas prácticas generales.
- Inserta la fila de negocio y la fila de outbox dentro de un único lote de transacción de Postgres, de modo que un fallo en cualquiera de las dos inserciones revierta ambas
- Usa un nodo Postgres Trigger que escuche las inserciones en la tabla de outbox para detectar nuevas filas; el disparador de base de datos subyacente solo existe mientras el flujo de trabajo esté publicado, y se elimina en cuanto se despublica
- Trata una llamada HTTP al receptor como confirmada solo ante una respuesta 2xx; trata cualquier otra cosa como no entregada
- Añade un flujo de trabajo de error, comenzando con un nodo Error Trigger, para que las ejecuciones fallidas del relé generen una alerta en lugar de fallar silenciosamente
Sources: How the Transactional Outbox Pattern Guarantees Event Delivery – n8n Blog, Postgres Trigger | Nodes | n8n Docs, HTTP Request | Nodes | n8n Docs, Handle errors gracefully | Build | n8n Docs, Postgres | Nodes | n8n Docs
Pasos de construcción: de la escritura atómica a la entrega confirmada

Con los requisitos previos y las restricciones establecidos, construye el relé por etapas dentro de un único flujo de trabajo de n8n, desde la escritura atómica hasta la entrega confirmada. Cada etapa siguiente corresponde a uno o más nodos de ese flujo de trabajo.
Secuencia de construcción del relé de outbox
- Escribe el par: En un único lote de transacción de Postgres, inserta la fila de negocio y una fila de outbox con estado pendiente; si alguna inserción falla, ambas se revierten.
- Detecta nuevas filas: Recoge la fila pendiente con un nodo Postgres Trigger que escuche las inserciones en la tabla de outbox.
- Publica el evento: Envía el payload de la fila al sistema receptor con un nodo HTTP Request, o entrégalo a un broker como RabbitMQ usando el nodo RabbitMQ de n8n.
- Comprueba la confirmación: Bifurca con un nodo If según si la llamada devolvió una respuesta 2xx, tratando cualquier otro resultado como no entregado.
- Marca la fila como procesada: Solo en la rama confirmada, actualiza el estado de la fila de outbox a procesado con un nodo Postgres.
- Gestiona el fallo: En la rama sin confirmar, usa un nodo Stop and Error para que la ejecución falle de forma visible y el flujo de trabajo de error adjunto pueda alertar al equipo.
El enfoque de detección y el destino receptor que elijas cambian algunos detalles, pero la forma del patrón transactional outbox se mantiene igual en todo momento: nada se marca como procesado hasta que el lado receptor realmente haya dicho que sí.
Sources: Postgres | Nodes | n8n Docs, How the Transactional Outbox Pattern Guarantees Event Delivery – n8n Blog, Postgres Trigger | Nodes | n8n Docs, RabbitMQ | Nodes | n8n Docs, HTTP Request | Nodes | n8n Docs, If | Nodes | n8n Docs, Handle errors gracefully | Build | n8n Docs
Criterios de finalización y resolución de problemas
Sabrás que el ejercicio está terminado cuando el flujo de trabajo se comporte correctamente tanto en el éxito como en el fallo. Usa lo siguiente como tu comprobación de finalización, y rompe deliberadamente la conexión con el receptor al menos una vez para probar también la ruta de fallo, no solo la ruta feliz.
Si las filas se quedan atascadas en pendiente, comprueba dos cosas primero: si el flujo de trabajo está realmente publicado, ya que el disparador de base de datos subyacente de un nodo Postgres Trigger solo existe mientras lo esté, y si el nodo HTTP Request está recibiendo una respuesta 2xx genuina en lugar de una redirección o una página de error disfrazada de éxito.
Sources: Postgres | Nodes | n8n Docs, HTTP Request | Nodes | n8n Docs, How the Transactional Outbox Pattern Guarantees Event Delivery – n8n Blog, Handle errors gracefully | Build | n8n Docs, Postgres Trigger | Nodes | n8n Docs
Reflexión y esquema de solución sugerido
Un esquema de solución razonable: dos consultas Postgres en un único lote de transacción para la escritura, un nodo Postgres Trigger para la detección, un nodo HTTP Request para la publicación, un nodo If que comprueba el código de estado, un nodo Postgres en la rama de éxito para marcar la fila como procesada, y un nodo Stop and Error en la rama de fallo que alimenta un flujo de trabajo de Error Trigger que te notifica.
Si tu destino receptor es un broker de mensajes en lugar de un endpoint HTTP, sustituye el nodo HTTP Request y su comprobación de código de estado por el nodo RabbitMQ de n8n, y actualiza la fila de outbox solo cuando tengas una confirmación equivalente desde el paso del broker.
Este es un ejercicio de práctica personal o de equipo, no una implementación lista para producción: los pasos anteriores son un diseño editorial construido a partir de capacidades documentadas de n8n. Antes de confiar en este patrón contra una instancia de producción compartida, trátalo como un punto de partida que tu propio equipo adapta a su esquema, su destino receptor y sus modos de fallo.
Sources: How the Transactional Outbox Pattern Guarantees Event Delivery – n8n Blog, Postgres Trigger | Nodes | n8n Docs, Postgres | Nodes | n8n Docs, Handle errors gracefully | Build | n8n Docs, HTTP Request | Nodes | n8n Docs, If | Nodes | n8n Docs


