GH GambleHub

Patrón de saga y transacciones distribuidas

Patrón de saga y transacciones distribuidas

1) Por qué se necesitan sagas

El 2PC clásico (fijación bifásica) no escala bien, se complica bajo fallas y bloquea los recursos. La saga divide el proceso general del negocio en una secuencia de transacciones locales (pasos), cada una de las cuales comulga de forma independiente. Si falla, los pasos siguientes se cancelan y los ya realizados se compensan con operaciones inversas.
Resultado: consistencia eventual administrada sin bloqueo global, alta vitalidad y protocolo de recuperación claro.

2) Modelos básicos

2. 1 Orquesta

El coordinador dedicado de la saga controla los pasos: envía comandos, espera respuestas/eventos, inicia compensaciones.
Pros: control centralizado, observabilidad simple, deduplines explícitos. Contras: componente adicional.

2. 2 Coreografía

No hay coordinador; los servicios responden a los eventos de cada uno («OrderPlaced» → «PaymentCaptured» → «InventoryReserved»...).
Pros: conectividad débil. Contras: más difícil de rastrear, el riesgo de un «baile de la muerte» sin reglas claras.

2. 3 TCC (Try-Confirm/Cancel)

Opción con «congelación» de recursos:

1. Try - preparación/reserva,

2. Confirmar - Confirmar,

3. Cancel - retroceso.

Las garantías son más altas, pero más difíciles son los contratos y los timeouts de las reservas.

3) Contratos de pasos y compensación

Cada paso = transacción local + compensación (idempotente, permite la repetición).
La compensación no está obligada por completo a «devolver la paz» - suficiente equivalencia de dominio (por ejemplo, «pagar la devolución» en lugar de «eliminar el pago»).
Identificar invariantes: para el dinero - el saldo no va a menos; para pedidos - no hay estados «dependientes».
Introduzca los deduplines/TTL de las reservas y el «garbage collector» para los intentos caducados.

4) Coherencia y semántica de la entrega

Entrega de mensajes: at-least-once (default) → todas las operaciones deben ser idempotentes.
Orden: importante por clave de correlación (por ejemplo, 'order _ id', 'player _ id').
Exactly-once no es el objetivo de la saga; logramos una uniforme-unidimensional efectiva a través de llaves idempotentes, outbox/inbox y una correcta comitiva.

5) El estado de la saga y su registro

Qué almacenar:
  • 'saga _ id', 'correlation _ id', estado actual (Running/Completed/Compensating/Compensated/Failed),
  • paso y sus variables (ID de pagos/reservas),
  • historial (registro) de eventos/decisiones, tiempos de espera, líneas de espera, número de retiros.
Dónde almacenar:
  • Tienda de Saga independiente (tabla/documento) disponible para el coordinador.
  • Para la coreografía, son los «agentes» locales de la saga los que publican eventos de estatus en un topic general.

6) Patrones de publicación confiable: outbox/inbox

Outbox: el paso commite el cambio y registra el evento/comando en la tabla de outbox en una sola transacción; El ladrón publica en el neumático.
Inbox: el consumidor mantiene una tabla de 'message _ id' procesado → dedoop + idempotencia.
Después de un efecto secundario exitoso, commitim offset/ACK (Kafka/RabbitMQ) no antes.

7) Diseño de los pasos de la saga

7. 1 Ejemplo (compra en iGaming/e-commerce)

1. PlaceOrder → el estado 'PENDING'.
2. AuthorizePayment (Try) → `payment_hold_id`.
3. ReserveInventory → `reservation_id`.
4. CapturePayment (Confirm).
5. FinalizeOrder → `COMPLETED`.

Compensación:
  • si (3) falló → 'CancelPaymentHold';
  • si (4) falló tras (3) → 'ReleaseInventory';
  • si (5) falló → 'RefundPayment' y 'ReleaseInventory'.

7. 2 Deduplines/Retraídas

Máximo N retraídas con retardo exponencial + jitter.
Después de superar - ir a 'Compensating'.
Almacena next_attempt_at y deadline_at para cada paso.

8) Orquestador vs plataforma

Opciones:
  • Orquestador casero ligero (microservicio + tabla Saga).
  • Las plataformas: Temporal/Cadence, Camunda, Netflix Conductor, Zeebe - dan temporizadores, retraídas, workflow de larga vida, visibilidad y consola web.
  • Para la coreografía, utilice el catálogo de eventos y la estricta convención de estado/claves.

9) Protocolos de integración

9. 1 Asincrónico (Kafka/RabbitMQ)

Comandos: 'payments. authorize. v1`, `inventory. reserve. v1`.
Eventos: 'payments. authorized. v1`, `inventory. reserved. v1`, `payments. captured. v1`, `payments. refunded. v1`.
Clave de lote = 'order _ id '/' player _ id' para orden.

9. 2 Sincronizado (HTTP/gRPC) dentro del paso

Es admisible para pasos «cortos», pero siempre con timeouts/retraídas/idempotencia y fallback en compensación asíncrona.

10) Idempotencia y llaves

En las solicitudes de comandos y compensaciones, pasa 'idempotency _ key'.
Los efectos secundarios (escritura en el DB/cargo) se ejecutan de forma condicional: «ejecutar si aún no se ha visto 'idempotency _ key'».
Las compensaciones también son idempotentes: la repetición de 'RefundPayment (id = X)' es segura.

11) Manejo de errores

Clases:
  • Transient (redes/temporizadores) → retrai/backoff.
  • Business (fondos insuficientes, límites) → compensación inmediata/vía alternativa.
  • Irrecoverable (infracción invariante) → intervención manual, compensación «manual».
  • Construya una matriz de soluciones: tipo de error → acción (retry/compensate/escalate).

12) Observabilidad y SLO sagas

SLI/SLO:
  • End-to-end latency sags (p50/p95/p99).
  • Tasa de éxito (porcentaje completado sin compensación).
  • Mean time to compensate и compensation rate.
  • sagas Orphaned (colgando) y el tiempo hasta GC.
  • Seguimiento: 'trace _ id '/' saga _ id' como enlace span entre pasos; métricas burn-rate para presupuestos de errores.

Logs: cada cambio de estado de la saga = registro estructurado con causa.

13) Ejemplos (pseudocódigo)

13. 1 Orquestador (idea)

python def handle(OrderPlaced e):
saga = Saga. start(e. order_id)
saga. run(step=authorize_payment, compensate=cancel_payment)
saga. run(step=reserve_inventory, compensate=release_inventory)
saga. run(step=capture_payment, compensate=refund_payment)
saga. run(step=finalize_order, compensate=refund_and_release)
saga. complete()

def run(step, compensate):
try:
step () # local transaction + outbox except Transient:
schedule_retry()
except Business as err:
start_compensation(err)

13. 2 Outbox (idea de la tabla)


outbox(id PK, aggregate_id, event_type, payload, created_at, sent_at NULL)
inbox(message_id PK, processed_at, status)
saga(order_id PK, state, step, next_attempt_at, deadline_at, context JSONB)
saga_log(id PK, order_id, time, event, details)

13. 3 Coreografía (ideas temáticas)

`orders. placed '→ consumidores: ' payments. authorize`, `inventory. reserve`

`payments. authorized` + `inventory. reserved` → `orders. try_finalize`

Cualquier rechazo → 'orders. compensate '→ se inician' payments. cancel/refund`, `inventory. release`.

14) Comparación con 2PC y ES

2PC: fuerte coherencia, pero bloqueos, cuellos de botella, «tubos de cobre».
Saga: consistencia eventual, se necesita disciplina de compensación y telemetría.
Event Sourcing: almacena los eventos como fuente de la verdad; las sagas en él son naturales, pero añaden la complejidad de las migraciones/snapshots.

15) Seguridad y cumplimiento

Seguridad de transporte (TLS/mTLS), ACL per topic/queue.
En eventos, un mínimo de PII, cifrado de campos sensibles, tokenización.
Auditoría de acceso a sagas y registros de compensación.
SLA con proveedores externos (pagos/envíos) = parámetros de los límites de deduplines y retrés.

16) Lista de verificación de implementación (0-45 días)

0-10 días

Destacar los procesos candidatos (multiservicios, con compensación).
Seleccione un modelo (orquestación/coreografía/TSS) y una clave de correlación.
Describa los pasos/compensaciones, invariantes y deduplines. Levanta las tablas 'saga', 'outbox', 'inbox'.

11-25 días

Incluye outbox/inbox, idempotencia y retraídas con backoff.
Aplota las primeras sagas; agregue los dashboards SLI/SLO y el rastreo.
Escriba las compensaciones runbook (incluyendo manuales) y escaladas.

26-45 días

Automatice las sagas GC «colgantes», reinicios/continuaciones periódicas por línea de salida.
Pase el día del juego: error del paso, exceso de línea de salida, no disponibilidad del corredor.
Estandarice los contratos de eventos (versiones, compatibilidad), establezca un «catálogo de sagas».

17) Anti-patrones

«Compensación = eliminar de la DB» en lugar de la acción inversa correcta del dominio.
No outbox/inbox → pérdida de eventos/efectos dobles.
Retrés sin jitter → dependencias DDoS.
La expectativa de una fuerte coherencia en la lectura sin el «proceso en curso»....
Un orquestador gigante en todo → monolito de control.
Coreografía total sin visibilidad y SLA → un baile inmanejable.
Ignorando los deadlines → las reservas/colinas eternas.

18) Métricas de madurez

≥ 90% de los procesos críticos están cubiertos por sagas/compensaciones y tienen invariantes descritos.
Outbox/inbox están integrados para todos los productores/consumidores de Tier-0/1.
SLO: p95 end-to-end sagas normalmente, success rate estable, orphaned <objetivo.
Trazados transparentes y dashboards «por pasos», alertas burn-rate.
Juego-día trimestral y verificación de runbook-compensación manual.

19) Conclusión

La saga es un contrato de consistencia práctico para sistemas distribuidos: pasos claros y acciones inversas, disciplina de publicación (outbox/inbox), dlines y retrases, observabilidad y procesos de compensación. Elija un modelo (orquestación/coreografía/TSS), fije invariantes y llaves, haga que los manejadores sean idempotentes, y sus procesos de negocio multiservicios se volverán predecibles y sostenibles sin un 2PC costoso.

Contact

Póngase en contacto

Escríbanos ante cualquier duda o necesidad de soporte.¡Siempre estamos listos para ayudarle!

Iniciar integración

El Email es obligatorio. Telegram o WhatsApp — opcionales.

Su nombre opcional
Email opcional
Asunto opcional
Mensaje opcional
Telegram opcional
@
Si indica Telegram, también le responderemos allí además del Email.
WhatsApp opcional
Formato: +código de país y número (por ejemplo, +34XXXXXXXXX).

Al hacer clic en el botón, usted acepta el tratamiento de sus datos.