{"id":199,"date":"2026-08-23T16:01:47","date_gmt":"2026-08-23T19:01:47","guid":{"rendered":"https:\/\/solidchain.ar\/?p=199"},"modified":"2026-08-23T16:14:30","modified_gmt":"2026-08-23T19:14:30","slug":"patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios","status":"publish","type":"post","link":"https:\/\/solidchain.ar\/index.php\/2026\/08\/23\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\/","title":{"rendered":"Patr\u00f3n Outbox: evitando la inconsistencia de datos en sistemas distribuidos y microservicios"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Cuando empezamos a trabajar con microservicios aparece un problema que, a primera vista, parece sencillo:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Guardar informaci\u00f3n en una base de datos y, al mismo tiempo, publicar un mensaje en RabbitMQ o Kafka.<\/strong><\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Por ejemplo, imaginemos un microservicio de <strong>Pedidos<\/strong>. Cuando un usuario confirma una compra necesitamos:<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li>Guardar el pedido en la base de datos.<\/li>\n\n\n\n<li>Publicar un evento <code>PedidoCreado<\/code>.<\/li>\n\n\n\n<li>Permitir que otros servicios \u2014Facturaci\u00f3n, Stock, Notificaciones, etc.\u2014 reaccionen a ese evento.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">El c\u00f3digo podr\u00eda parecer conceptualmente as\u00ed:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>BEGIN TRANSACTION\n\nINSERT INTO pedidos (...)\n\nCOMMIT\n\nPublicarEvento(\"PedidoCreado\")<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">El problema est\u00e1 justamente entre el <code>COMMIT<\/code> y la publicaci\u00f3n del evento.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00bfQu\u00e9 pasa si la base de datos confirma correctamente la transacci\u00f3n, pero RabbitMQ o Kafka no est\u00e1n disponibles?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Terminamos con un pedido que <strong>existe en nuestra base de datos pero que ning\u00fan otro sistema sabe que existe<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Y eso es uno de los problemas cl\u00e1sicos de consistencia en arquitecturas distribuidas.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">El problema de las dos transacciones<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Cuando una operaci\u00f3n involucra dos sistemas diferentes tenemos, en realidad, dos transacciones independientes:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La base de datos puede confirmar su transacci\u00f3n, pero eso no significa que el broker vaya a aceptar posteriormente el mensaje.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"844\" height=\"312\" src=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image.png\" alt=\"\" class=\"wp-image-201\" srcset=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image.png 844w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-300x111.png 300w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-768x284.png 768w\" sizes=\"auto, (max-width: 844px) 100vw, 844px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Tambi\u00e9n podr\u00eda ocurrir lo contrario:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1. Publicamos el mensaje\n2. El broker confirma\n3. Intentamos guardar en la base\n4. La transacci\u00f3n de base de datos falla<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Ahora otros servicios reciben un evento indicando que ocurri\u00f3 algo que, desde el punto de vista de nuestro sistema, <strong>nunca ocurri\u00f3<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"839\" height=\"368\" src=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-1.png\" alt=\"\" class=\"wp-image-202\" srcset=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-1.png 839w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-1-300x132.png 300w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-1-768x337.png 768w\" sizes=\"auto, (max-width: 839px) 100vw, 839px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">\u00bfPor qu\u00e9 no meter todo dentro de una \u00fanica transacci\u00f3n?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ser\u00eda ideal poder hacer algo as\u00ed:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>BEGIN TRANSACTION\n\nINSERT INTO pedidos (...)\n\nPUBLISH PedidoCreado\n\nCOMMIT<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">El problema es que el <code>COMMIT<\/code> de nuestra base de datos solamente controla recursos pertenecientes a esa base de datos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">RabbitMQ o Kafka son sistemas externos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Para intentar garantizar atomicidad entre ambos podr\u00edamos utilizar mecanismos de <strong>transacciones distribuidas<\/strong>, generalmente asociados a protocolos como:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Two-Phase Commit (2PC)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Pero esto introduce bastante complejidad.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Entre otras cosas:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>mayor acoplamiento entre componentes;<\/li>\n\n\n\n<li>peor disponibilidad;<\/li>\n\n\n\n<li>bloqueo de recursos;<\/li>\n\n\n\n<li>infraestructura adicional;<\/li>\n\n\n\n<li>mayor dificultad operativa;<\/li>\n\n\n\n<li>problemas de compatibilidad entre tecnolog\u00edas;<\/li>\n\n\n\n<li>menor tolerancia a fallas.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">En arquitecturas modernas de microservicios normalmente intentamos evitar este tipo de coordinaci\u00f3n distribuida.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Y es justamente aqu\u00ed donde aparece el <strong>Transactional Outbox Pattern<\/strong>.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">\u00bfQu\u00e9 es el patr\u00f3n Outbox?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">La idea es sorprendentemente simple.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En lugar de intentar guardar informaci\u00f3n en la base de datos <strong>y publicar directamente el mensaje<\/strong>, guardamos ambas cosas en la misma base de datos y dentro de la misma transacci\u00f3n.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"797\" height=\"341\" src=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-2.png\" alt=\"\" class=\"wp-image-203\" srcset=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-2.png 797w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-2-300x128.png 300w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-2-768x329.png 768w\" sizes=\"auto, (max-width: 797px) 100vw, 797px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Para eso agregamos una tabla llamada, por ejemplo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Outbox<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">El flujo pasa a ser:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>BEGIN TRANSACTION\n\nINSERT INTO pedidos (...)\n\nINSERT INTO outbox (...)\n\nCOMMIT<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">La tabla podr\u00eda tener una estructura similar a esta:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE TABLE outbox_messages (\n    id UUID PRIMARY KEY,\n    event_type VARCHAR(100) NOT NULL,\n    aggregate_id VARCHAR(100) NOT NULL,\n    payload JSONB NOT NULL,\n    created_at TIMESTAMP NOT NULL,\n    processed_at TIMESTAMP NULL\n);<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Cuando creamos un pedido:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>INSERT INTO pedidos (\n    id,\n    cliente_id,\n    total\n)\nVALUES (\n    'PED-123',\n    'CLI-456',\n    25000\n);<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">dentro de la misma transacci\u00f3n insertamos:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>INSERT INTO outbox_messages (\n    id,\n    event_type,\n    aggregate_id,\n    payload,\n    created_at\n)\nVALUES (\n    'EVT-789',\n    'PedidoCreado',\n    'PED-123',\n    '{\n        \"pedidoId\": \"PED-123\",\n        \"clienteId\": \"CLI-456\",\n        \"total\": 25000\n    }',\n    NOW()\n);<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Entonces ocurre algo importante:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Pedido + Evento<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">se guardan dentro de <strong>una \u00fanica transacci\u00f3n ACID<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Si la transacci\u00f3n falla:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Pedido      \u274c\nEvento      \u274c<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Si la transacci\u00f3n funciona:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Pedido      \u2705\nEvento      \u2705<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Desde el punto de vista de nuestra base de datos ya no puede existir uno sin el otro.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Pero todav\u00eda no publicamos nada<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Exactamente.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El registro de la tabla Outbox todav\u00eda est\u00e1 solamente en nuestra base de datos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ahora necesitamos otro componente que se encargue de leer los eventos pendientes y publicarlos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Podemos llamarlo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Outbox Publisher<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">o:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Message Relay<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">La arquitectura queda as\u00ed:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-3-1024x768.png\" alt=\"\" class=\"wp-image-205\" srcset=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-3-1024x768.png 1024w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-3-300x225.png 300w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-3-768x576.png 768w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-3.png 1448w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">El publisher busca peri\u00f3dicamente mensajes pendientes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT *\nFROM outbox_messages\nWHERE processed_at IS NULL\nORDER BY created_at;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Luego publica cada mensaje en el broker.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Por ejemplo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Exchange \/ Topic:\n\npedidos.events<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">con:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"eventId\": \"EVT-789\",\n  \"eventType\": \"PedidoCreado\",\n  \"pedidoId\": \"PED-123\",\n  \"clienteId\": \"CLI-456\",\n  \"total\": 25000\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Una vez confirmado por RabbitMQ o Kafka, podemos marcarlo como procesado:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>UPDATE outbox_messages\nSET processed_at = NOW()\nWHERE id = 'EVT-789';<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">\u00bfQu\u00e9 ocurre si RabbitMQ est\u00e1 ca\u00eddo?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Ac\u00e1 aparece una de las principales ventajas del patr\u00f3n.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Supongamos que tenemos:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"320\" src=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-5-1024x320.png\" alt=\"\" class=\"wp-image-207\" srcset=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-5-1024x320.png 1024w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-5-300x94.png 300w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-5-768x240.png 768w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-5.png 1416w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">No perdemos el evento.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Simplemente queda pendiente:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>processed_at = NULL<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Cuando RabbitMQ vuelva a estar disponible, el publisher podr\u00e1 volver a intentarlo<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Esto desacopla completamente la disponibilidad del broker de la transacci\u00f3n del negocio.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La creaci\u00f3n del pedido <strong>no necesita que RabbitMQ est\u00e9 disponible exactamente en ese instante<\/strong>.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Entonces conseguimos consistencia eventual<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Es importante entender que Outbox no proporciona consistencia inmediata entre todos los microservicios.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Proporciona algo diferente:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Consistencia eventual<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Durante algunos segundos podr\u00edamos tener:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Servicio Pedidos\nPedido PED-123 \u2192 existente\n\nServicio Facturaci\u00f3n\nPedido PED-123 \u2192 todav\u00eda desconocido<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Despu\u00e9s de que el evento sea publicado y procesado:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Servicio Pedidos\nPedido PED-123 \u2192 existente\n\nServicio Facturaci\u00f3n\nPedido PED-123 \u2192 factura generada<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Los sistemas terminan convergiendo hacia un estado consistente.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Este modelo encaja mucho mejor con arquitecturas distribuidas donde buscamos:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>desacoplamiento + resiliencia + escalabilidad<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">en lugar de intentar que todos los componentes participen en una \u00fanica transacci\u00f3n global.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Hay un problema adicional: mensajes duplicados<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Imaginemos esta situaci\u00f3n:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"542\" src=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-6-1024x542.png\" alt=\"\" class=\"wp-image-208\" srcset=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-6-1024x542.png 1024w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-6-300x159.png 300w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-6-768x406.png 768w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-6.png 1397w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Cuando el proceso vuelva a levantarse encontrar\u00e1:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>EVT-789\nprocessed_at = NULL<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">y volver\u00e1 a publicarlo.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Resultado:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PedidoCreado\nPedidoCreado<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">dos veces.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Por eso un sistema basado en Outbox normalmente trabaja con una garant\u00eda similar a:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>At Least Once Delivery<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Es decir:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">El evento se publicar\u00e1 al menos una vez, pero podr\u00eda publicarse m\u00e1s de una vez.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Y esto introduce otro concepto fundamental.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Los consumidores deben ser idempotentes<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Supongamos que Facturaci\u00f3n recibe:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>eventId = EVT-789<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">La primera vez:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Genera factura<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Si recibe nuevamente:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>eventId = EVT-789<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">no deber\u00eda generar otra factura.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Una estrategia habitual consiste en guardar los eventos ya procesados:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>processed_events<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Por ejemplo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE TABLE processed_events (\n    event_id UUID PRIMARY KEY,\n    processed_at TIMESTAMP NOT NULL\n);<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Antes de procesar:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT event_id\nFROM processed_events\nWHERE event_id = 'EVT-789';<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Si existe:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ignorar evento<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Si no existe:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>procesar evento\nguardar event_id<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">De esta forma podemos hacer que:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Procesar 1 vez\nProcesar 2 veces\nProcesar 10 veces<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">termine produciendo el mismo resultado.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Esta propiedad se conoce como:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Idempotencia<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Y es uno de los conceptos m\u00e1s importantes cuando trabajamos con sistemas orientados a eventos.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Outbox + Idempotencia<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">En la pr\u00e1ctica ambos patrones suelen aparecer juntos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El productor utiliza:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Transactional Outbox<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">para garantizar que el evento no se pierda.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El consumidor utiliza:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Idempotent Consumer<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">para garantizar que un evento duplicado no genere inconsistencias.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El flujo completo queda:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"819\" height=\"1024\" src=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-9-819x1024.png\" alt=\"\" class=\"wp-image-211\" srcset=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-9-819x1024.png 819w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-9-240x300.png 240w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-9-768x960.png 768w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-9.png 1122w\" sizes=\"auto, (max-width: 819px) 100vw, 819px\" \/><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\">\u00bfC\u00f3mo ejecutar el Outbox Publisher?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Hay varias estrategias.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"628\" src=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-7-1024x628.png\" alt=\"\" class=\"wp-image-209\" srcset=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-7-1024x628.png 1024w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-7-300x184.png 300w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-7-768x471.png 768w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-7.png 1370w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">1. Polling<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">La opci\u00f3n m\u00e1s sencilla.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Un proceso ejecuta peri\u00f3dicamente:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT *\nFROM outbox_messages\nWHERE processed_at IS NULL\nLIMIT 100;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Por ejemplo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cada 1 segundo<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">o:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cada 5 segundos<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Ventajas:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>simple;<\/li>\n\n\n\n<li>f\u00e1cil de implementar;<\/li>\n\n\n\n<li>f\u00e1cil de diagnosticar;<\/li>\n\n\n\n<li>pr\u00e1cticamente independiente de la tecnolog\u00eda.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Desventajas:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>agrega consultas peri\u00f3dicas;<\/li>\n\n\n\n<li>introduce cierta latencia;<\/li>\n\n\n\n<li>necesita controlar concurrencia.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Para muchos sistemas empresariales esta soluci\u00f3n es m\u00e1s que suficiente.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Worker permanente<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">En lugar de un proceso peri\u00f3dico podemos tener un servicio dedicado:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Outbox Worker<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">que se ejecuta permanentemente.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Por ejemplo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.NET Worker Service\nJava Spring Worker\nNode.js Worker\nPHP Worker<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">El worker puede procesar registros constantemente y aplicar pol\u00edticas de retry.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Por ejemplo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>retry 1 \u2192 5 segundos\nretry 2 \u2192 30 segundos\nretry 3 \u2192 2 minutos\nretry 4 \u2192 10 minutos<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Esto suele implementarse mediante:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>exponential backoff<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">3. Change Data Capture<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Una alternativa m\u00e1s sofisticada consiste en no consultar constantemente la tabla.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Podemos utilizar:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Change Data Capture<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">para detectar nuevos registros.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Herramientas como:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Debezium\nKafka Connect<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">pueden leer directamente el transaction log de la base de datos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La arquitectura podr\u00eda ser:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"819\" height=\"1024\" src=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-10-819x1024.png\" alt=\"\" class=\"wp-image-212\" srcset=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-10-819x1024.png 819w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-10-240x300.png 240w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-10-768x960.png 768w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-10.png 1122w\" sizes=\"auto, (max-width: 819px) 100vw, 819px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">La aplicaci\u00f3n sigue escribiendo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Negocio + Outbox<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">en una \u00fanica transacci\u00f3n, pero la publicaci\u00f3n de eventos puede realizarse observando los cambios del log de la base de datos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Esto evita gran parte del polling y puede funcionar muy bien en arquitecturas de gran volumen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A cambio introduce m\u00e1s infraestructura y complejidad operativa.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Un Outbox real necesita algo m\u00e1s que un payload<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">En producci\u00f3n probablemente nuestra tabla termine teniendo m\u00e1s informaci\u00f3n.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Por ejemplo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE TABLE outbox_messages (\n    id UUID PRIMARY KEY,\n    aggregate_type VARCHAR(100),\n    aggregate_id VARCHAR(100),\n    event_type VARCHAR(100),\n    payload JSONB,\n    created_at TIMESTAMP,\n    processed_at TIMESTAMP,\n    retry_count INT DEFAULT 0,\n    last_error TEXT\n);<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Esto nos permite observar cosas como:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Evento: PedidoCreado\nPedido: PED-123\nIntentos: 4\n\u00daltimo error: RabbitMQ unavailable\nEstado: Pending<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Y ah\u00ed aparece algo que muchas veces se subestima:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">El Outbox tambi\u00e9n se convierte en una herramienta de observabilidad.<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Podemos saber exactamente qu\u00e9 eventos:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>fueron generados;<\/li>\n\n\n\n<li>fueron publicados;<\/li>\n\n\n\n<li>est\u00e1n pendientes;<\/li>\n\n\n\n<li>fallaron;<\/li>\n\n\n\n<li>fueron reintentados.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Esto facilita much\u00edsimo investigar problemas en producci\u00f3n.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">\u00bfY qu\u00e9 hacemos con los registros procesados?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Una tabla Outbox puede crecer r\u00e1pidamente.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Supongamos:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>100 eventos por segundo<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Eso representa aproximadamente:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>8.640.000 eventos diarios<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Por eso normalmente necesitamos una pol\u00edtica de limpieza.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Por ejemplo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>DELETE FROM outbox_messages\nWHERE processed_at &lt; NOW() - INTERVAL '7 days';<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Tambi\u00e9n podemos:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>archivar eventos;<\/li>\n\n\n\n<li>mover registros hist\u00f3ricos;<\/li>\n\n\n\n<li>particionar la tabla;<\/li>\n\n\n\n<li>ejecutar jobs de housekeeping.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">La estrategia depender\u00e1 de cu\u00e1nto valor tenga conservar el historial.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Outbox no significa exactamente once<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Es com\u00fan escuchar:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u201cCon Outbox conseguimos exactamente una entrega.\u201d<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">No necesariamente.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El patr\u00f3n Outbox garantiza principalmente que:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Cambio de negocio\n      +\nCreaci\u00f3n del evento<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">ocurran at\u00f3micamente.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pero la comunicaci\u00f3n con un broker sigue teniendo las caracter\u00edsticas propias de los sistemas distribuidos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Por eso el dise\u00f1o m\u00e1s realista suele ser:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Transactional Outbox\n        +\nAt-Least-Once Delivery\n        +\nIdempotent Consumers<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">En muchos sistemas esta combinaci\u00f3n es much\u00edsimo m\u00e1s robusta que intentar construir una garant\u00eda global de <code>exactly-once<\/code>.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Ejemplo completo<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Imaginemos un e-commerce.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Un usuario realiza una compra.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"625\" src=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-8-1024x625.png\" alt=\"\" class=\"wp-image-210\" srcset=\"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-8-1024x625.png 1024w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-8-300x183.png 300w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-8-768x469.png 768w, https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/image-8.png 1398w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Paso 1 \u2014 Pedidos<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">El servicio de Pedidos ejecuta:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>BEGIN TRANSACTION\n\ncrear Pedido PED-123\n\ncrear evento EVT-789\nPedidoCreado\n\nCOMMIT<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Tenemos:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pedidos\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nPED-123\n\noutbox\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nEVT-789 | PedidoCreado<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Paso 2 \u2014 Publicaci\u00f3n<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">El Outbox Publisher lee:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>EVT-789<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">y publica:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pedidos.creado<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">en Kafka o RabbitMQ.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Luego marca:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>EVT-789 \u2192 processed<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Paso 3 \u2014 Consumidores<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">El evento llega a:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Stock\nFacturaci\u00f3n\nNotificaciones\nAnalytics<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Cada sistema reacciona de manera independiente:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Stock\n\u2192 reserva productos\n\nFacturaci\u00f3n\n\u2192 genera factura\n\nNotificaciones\n\u2192 env\u00eda email\n\nAnalytics\n\u2192 registra la compra<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Ninguno necesita que el servicio de Pedidos llame directamente a los dem\u00e1s.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">\u00bfCu\u00e1ndo usar Transactional Outbox?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Es especialmente \u00fatil cuando tenemos:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>microservicios;<\/li>\n\n\n\n<li>arquitectura event-driven;<\/li>\n\n\n\n<li>RabbitMQ;<\/li>\n\n\n\n<li>Apache Kafka;<\/li>\n\n\n\n<li>Azure Service Bus;<\/li>\n\n\n\n<li>AWS SQS\/SNS;<\/li>\n\n\n\n<li>procesos de integraci\u00f3n;<\/li>\n\n\n\n<li>sincronizaci\u00f3n entre sistemas;<\/li>\n\n\n\n<li>operaciones que no pueden perder eventos.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Por ejemplo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Pedido creado\nPago confirmado\nUsuario registrado\nFactura emitida\nStock actualizado\nAlumno inscripto\nDocumento generado\nTransferencia iniciada<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Si perder uno de estos eventos puede dejar distintos sistemas en estados inconsistentes, Outbox es un patr\u00f3n que vale la pena considerar.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">\u00bfCu\u00e1ndo quiz\u00e1s no hace falta?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">No toda aplicaci\u00f3n necesita Outbox.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Si tenemos:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Frontend\n   \u2193\nBackend monol\u00edtico\n   \u2193\nUna \u00fanica base de datos<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">y todas las operaciones ocurren dentro de esa misma base de datos, probablemente una transacci\u00f3n tradicional sea suficiente.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Agregar:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Outbox\nWorkers\nBroker\nRetries\nIdempotencia\nObservabilidad<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">sin una necesidad real simplemente aumenta la complejidad.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Como casi siempre en arquitectura:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>un patr\u00f3n resuelve un problema; no deber\u00eda utilizarse solamente porque est\u00e1 de moda.<\/strong><\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Cuando empezamos a trabajar con microservicios aparece un problema que, a primera vista, parece sencillo: [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":216,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[13],"tags":[],"class_list":["post-199","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-arquitectura"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"Cuando empezamos a trabajar con microservicios aparece un problema que, a primera vista, parece sencillo: Guardar informaci\u00f3n en una base de datos y, al mismo tiempo, publicar un mensaje en RabbitMQ o Kafka. Por ejemplo, imaginemos un microservicio de Pedidos. Cuando un usuario confirma una compra necesitamos: Guardar el pedido en la base de datos.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"pedro.nmb@gmail.com\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/solidchain.ar\/index.php\/2026\/08\/23\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"solidchain.ar -\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Patr\u00f3n Outbox: evitando la inconsistencia de datos en sistemas distribuidos y microservicios - solidchain.ar\" \/>\n\t\t<meta property=\"og:description\" content=\"Cuando empezamos a trabajar con microservicios aparece un problema que, a primera vista, parece sencillo: Guardar informaci\u00f3n en una base de datos y, al mismo tiempo, publicar un mensaje en RabbitMQ o Kafka. Por ejemplo, imaginemos un microservicio de Pedidos. Cuando un usuario confirma una compra necesitamos: Guardar el pedido en la base de datos.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/solidchain.ar\/index.php\/2026\/08\/23\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-08-23T19:01:47+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-08-23T19:14:30+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Patr\u00f3n Outbox: evitando la inconsistencia de datos en sistemas distribuidos y microservicios - solidchain.ar\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Cuando empezamos a trabajar con microservicios aparece un problema que, a primera vista, parece sencillo: Guardar informaci\u00f3n en una base de datos y, al mismo tiempo, publicar un mensaje en RabbitMQ o Kafka. Por ejemplo, imaginemos un microservicio de Pedidos. Cuando un usuario confirma una compra necesitamos: Guardar el pedido en la base de datos.\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BlogPosting\",\"@id\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/2026\\\/08\\\/23\\\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\\\/#blogposting\",\"name\":\"Patr\\u00f3n Outbox: evitando la inconsistencia de datos en sistemas distribuidos y microservicios - solidchain.ar\",\"headline\":\"Patr\\u00f3n Outbox: evitando la inconsistencia de datos en sistemas distribuidos y microservicios\",\"author\":{\"@id\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/author\\\/pedro-nmbgmail-com\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/solidchain.ar\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/solidchain.ar\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/Imagen-de-Codex-23-ago-2026-16_13_47.png\",\"width\":1254,\"height\":1254},\"datePublished\":\"2026-08-23T16:01:47-03:00\",\"dateModified\":\"2026-08-23T16:14:30-03:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/2026\\\/08\\\/23\\\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/2026\\\/08\\\/23\\\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\\\/#webpage\"},\"articleSection\":\"Arquitectura\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/2026\\\/08\\\/23\\\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/solidchain.ar#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/solidchain.ar\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/category\\\/arquitectura\\\/#listItem\",\"name\":\"Arquitectura\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/category\\\/arquitectura\\\/#listItem\",\"position\":2,\"name\":\"Arquitectura\",\"item\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/category\\\/arquitectura\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/2026\\\/08\\\/23\\\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\\\/#listItem\",\"name\":\"Patr\\u00f3n Outbox: evitando la inconsistencia de datos en sistemas distribuidos y microservicios\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/solidchain.ar#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/2026\\\/08\\\/23\\\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\\\/#listItem\",\"position\":3,\"name\":\"Patr\\u00f3n Outbox: evitando la inconsistencia de datos en sistemas distribuidos y microservicios\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/category\\\/arquitectura\\\/#listItem\",\"name\":\"Arquitectura\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/solidchain.ar\\\/#organization\",\"name\":\"solidchain.ar\",\"url\":\"https:\\\/\\\/solidchain.ar\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/author\\\/pedro-nmbgmail-com\\\/#author\",\"url\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/author\\\/pedro-nmbgmail-com\\\/\",\"name\":\"pedro.nmb@gmail.com\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/2026\\\/08\\\/23\\\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/95afff8b8f7fe6b8d5961959ab9b7c2a86e9173ebf0d880eb606114b157e42fd?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"pedro.nmb@gmail.com\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/2026\\\/08\\\/23\\\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\\\/#webpage\",\"url\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/2026\\\/08\\\/23\\\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\\\/\",\"name\":\"Patr\\u00f3n Outbox: evitando la inconsistencia de datos en sistemas distribuidos y microservicios - solidchain.ar\",\"description\":\"Cuando empezamos a trabajar con microservicios aparece un problema que, a primera vista, parece sencillo: Guardar informaci\\u00f3n en una base de datos y, al mismo tiempo, publicar un mensaje en RabbitMQ o Kafka. Por ejemplo, imaginemos un microservicio de Pedidos. Cuando un usuario confirma una compra necesitamos: Guardar el pedido en la base de datos.\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/solidchain.ar\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/2026\\\/08\\\/23\\\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/author\\\/pedro-nmbgmail-com\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/author\\\/pedro-nmbgmail-com\\\/#author\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/solidchain.ar\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/Imagen-de-Codex-23-ago-2026-16_13_47.png\",\"@id\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/2026\\\/08\\\/23\\\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\\\/#mainImage\",\"width\":1254,\"height\":1254},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/solidchain.ar\\\/index.php\\\/2026\\\/08\\\/23\\\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\\\/#mainImage\"},\"datePublished\":\"2026-08-23T16:01:47-03:00\",\"dateModified\":\"2026-08-23T16:14:30-03:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/solidchain.ar\\\/#website\",\"url\":\"https:\\\/\\\/solidchain.ar\\\/\",\"name\":\"solidchain.ar\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/solidchain.ar\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Patr\u00f3n Outbox: evitando la inconsistencia de datos en sistemas distribuidos y microservicios - solidchain.ar","description":"Cuando empezamos a trabajar con microservicios aparece un problema que, a primera vista, parece sencillo: Guardar informaci\u00f3n en una base de datos y, al mismo tiempo, publicar un mensaje en RabbitMQ o Kafka. Por ejemplo, imaginemos un microservicio de Pedidos. Cuando un usuario confirma una compra necesitamos: Guardar el pedido en la base de datos.","canonical_url":"https:\/\/solidchain.ar\/index.php\/2026\/08\/23\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BlogPosting","@id":"https:\/\/solidchain.ar\/index.php\/2026\/08\/23\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\/#blogposting","name":"Patr\u00f3n Outbox: evitando la inconsistencia de datos en sistemas distribuidos y microservicios - solidchain.ar","headline":"Patr\u00f3n Outbox: evitando la inconsistencia de datos en sistemas distribuidos y microservicios","author":{"@id":"https:\/\/solidchain.ar\/index.php\/author\/pedro-nmbgmail-com\/#author"},"publisher":{"@id":"https:\/\/solidchain.ar\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/Imagen-de-Codex-23-ago-2026-16_13_47.png","width":1254,"height":1254},"datePublished":"2026-08-23T16:01:47-03:00","dateModified":"2026-08-23T16:14:30-03:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/solidchain.ar\/index.php\/2026\/08\/23\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\/#webpage"},"isPartOf":{"@id":"https:\/\/solidchain.ar\/index.php\/2026\/08\/23\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\/#webpage"},"articleSection":"Arquitectura"},{"@type":"BreadcrumbList","@id":"https:\/\/solidchain.ar\/index.php\/2026\/08\/23\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/solidchain.ar#listItem","position":1,"name":"Home","item":"https:\/\/solidchain.ar","nextItem":{"@type":"ListItem","@id":"https:\/\/solidchain.ar\/index.php\/category\/arquitectura\/#listItem","name":"Arquitectura"}},{"@type":"ListItem","@id":"https:\/\/solidchain.ar\/index.php\/category\/arquitectura\/#listItem","position":2,"name":"Arquitectura","item":"https:\/\/solidchain.ar\/index.php\/category\/arquitectura\/","nextItem":{"@type":"ListItem","@id":"https:\/\/solidchain.ar\/index.php\/2026\/08\/23\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\/#listItem","name":"Patr\u00f3n Outbox: evitando la inconsistencia de datos en sistemas distribuidos y microservicios"},"previousItem":{"@type":"ListItem","@id":"https:\/\/solidchain.ar#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/solidchain.ar\/index.php\/2026\/08\/23\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\/#listItem","position":3,"name":"Patr\u00f3n Outbox: evitando la inconsistencia de datos en sistemas distribuidos y microservicios","previousItem":{"@type":"ListItem","@id":"https:\/\/solidchain.ar\/index.php\/category\/arquitectura\/#listItem","name":"Arquitectura"}}]},{"@type":"Organization","@id":"https:\/\/solidchain.ar\/#organization","name":"solidchain.ar","url":"https:\/\/solidchain.ar\/"},{"@type":"Person","@id":"https:\/\/solidchain.ar\/index.php\/author\/pedro-nmbgmail-com\/#author","url":"https:\/\/solidchain.ar\/index.php\/author\/pedro-nmbgmail-com\/","name":"pedro.nmb@gmail.com","image":{"@type":"ImageObject","@id":"https:\/\/solidchain.ar\/index.php\/2026\/08\/23\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/95afff8b8f7fe6b8d5961959ab9b7c2a86e9173ebf0d880eb606114b157e42fd?s=96&d=mm&r=g","width":96,"height":96,"caption":"pedro.nmb@gmail.com"}},{"@type":"WebPage","@id":"https:\/\/solidchain.ar\/index.php\/2026\/08\/23\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\/#webpage","url":"https:\/\/solidchain.ar\/index.php\/2026\/08\/23\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\/","name":"Patr\u00f3n Outbox: evitando la inconsistencia de datos en sistemas distribuidos y microservicios - solidchain.ar","description":"Cuando empezamos a trabajar con microservicios aparece un problema que, a primera vista, parece sencillo: Guardar informaci\u00f3n en una base de datos y, al mismo tiempo, publicar un mensaje en RabbitMQ o Kafka. Por ejemplo, imaginemos un microservicio de Pedidos. Cuando un usuario confirma una compra necesitamos: Guardar el pedido en la base de datos.","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/solidchain.ar\/#website"},"breadcrumb":{"@id":"https:\/\/solidchain.ar\/index.php\/2026\/08\/23\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\/#breadcrumblist"},"author":{"@id":"https:\/\/solidchain.ar\/index.php\/author\/pedro-nmbgmail-com\/#author"},"creator":{"@id":"https:\/\/solidchain.ar\/index.php\/author\/pedro-nmbgmail-com\/#author"},"image":{"@type":"ImageObject","url":"https:\/\/solidchain.ar\/wp-content\/uploads\/2026\/08\/Imagen-de-Codex-23-ago-2026-16_13_47.png","@id":"https:\/\/solidchain.ar\/index.php\/2026\/08\/23\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\/#mainImage","width":1254,"height":1254},"primaryImageOfPage":{"@id":"https:\/\/solidchain.ar\/index.php\/2026\/08\/23\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\/#mainImage"},"datePublished":"2026-08-23T16:01:47-03:00","dateModified":"2026-08-23T16:14:30-03:00"},{"@type":"WebSite","@id":"https:\/\/solidchain.ar\/#website","url":"https:\/\/solidchain.ar\/","name":"solidchain.ar","inLanguage":"en-US","publisher":{"@id":"https:\/\/solidchain.ar\/#organization"}}]},"og:locale":"en_US","og:site_name":"solidchain.ar -","og:type":"article","og:title":"Patr\u00f3n Outbox: evitando la inconsistencia de datos en sistemas distribuidos y microservicios - solidchain.ar","og:description":"Cuando empezamos a trabajar con microservicios aparece un problema que, a primera vista, parece sencillo: Guardar informaci\u00f3n en una base de datos y, al mismo tiempo, publicar un mensaje en RabbitMQ o Kafka. Por ejemplo, imaginemos un microservicio de Pedidos. Cuando un usuario confirma una compra necesitamos: Guardar el pedido en la base de datos.","og:url":"https:\/\/solidchain.ar\/index.php\/2026\/08\/23\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\/","article:published_time":"2026-08-23T19:01:47+00:00","article:modified_time":"2026-08-23T19:14:30+00:00","twitter:card":"summary_large_image","twitter:title":"Patr\u00f3n Outbox: evitando la inconsistencia de datos en sistemas distribuidos y microservicios - solidchain.ar","twitter:description":"Cuando empezamos a trabajar con microservicios aparece un problema que, a primera vista, parece sencillo: Guardar informaci\u00f3n en una base de datos y, al mismo tiempo, publicar un mensaje en RabbitMQ o Kafka. Por ejemplo, imaginemos un microservicio de Pedidos. Cuando un usuario confirma una compra necesitamos: Guardar el pedido en la base de datos."},"aioseo_meta_data":{"post_id":"199","title":null,"description":null,"keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"BlogPosting","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":{"subject":"","preview":"","content":""},"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"created":"2026-08-23 18:36:04","updated":"2026-08-23 19:26:42","seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/solidchain.ar\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/solidchain.ar\/index.php\/category\/arquitectura\/\" title=\"Arquitectura\">Arquitectura<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tPatr\u00f3n Outbox: evitando la inconsistencia de datos en sistemas distribuidos y microservicios\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/solidchain.ar"},{"label":"Arquitectura","link":"https:\/\/solidchain.ar\/index.php\/category\/arquitectura\/"},{"label":"Patr\u00f3n Outbox: evitando la inconsistencia de datos en sistemas distribuidos y microservicios","link":"https:\/\/solidchain.ar\/index.php\/2026\/08\/23\/patron-outbox-evitando-la-inconsistencia-de-datos-en-sistemas-distribuidos-y-microservicios\/"}],"_links":{"self":[{"href":"https:\/\/solidchain.ar\/index.php\/wp-json\/wp\/v2\/posts\/199","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/solidchain.ar\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/solidchain.ar\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/solidchain.ar\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/solidchain.ar\/index.php\/wp-json\/wp\/v2\/comments?post=199"}],"version-history":[{"count":3,"href":"https:\/\/solidchain.ar\/index.php\/wp-json\/wp\/v2\/posts\/199\/revisions"}],"predecessor-version":[{"id":215,"href":"https:\/\/solidchain.ar\/index.php\/wp-json\/wp\/v2\/posts\/199\/revisions\/215"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/solidchain.ar\/index.php\/wp-json\/wp\/v2\/media\/216"}],"wp:attachment":[{"href":"https:\/\/solidchain.ar\/index.php\/wp-json\/wp\/v2\/media?parent=199"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/solidchain.ar\/index.php\/wp-json\/wp\/v2\/categories?post=199"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/solidchain.ar\/index.php\/wp-json\/wp\/v2\/tags?post=199"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}