0
0
RabbitMQdevops~7 mins

Saga pattern for distributed transactions in RabbitMQ - Commands & Configuration

Choose your learning style9 modes available
Introduction
When multiple services need to work together to complete a task, sometimes one service fails and leaves the system in a bad state. The Saga pattern helps by breaking the task into smaller steps and making sure each step can be undone if something goes wrong, keeping everything consistent.
When you have multiple microservices that must update their data together but cannot use a single database transaction.
When you want to ensure that if one step in a process fails, previous steps can be reversed to avoid partial updates.
When you need to coordinate order processing, payment, and inventory updates across different systems.
When you want to use RabbitMQ to send messages that trigger each step and handle failures with compensating actions.
When you want to improve reliability and consistency in distributed systems without locking resources for a long time.
Config File - rabbitmq_saga_config.json
rabbitmq_saga_config.json
{
  "saga": {
    "steps": [
      {
        "name": "reserve_inventory",
        "queue": "inventory_reserve_queue",
        "compensate_queue": "inventory_release_queue"
      },
      {
        "name": "process_payment",
        "queue": "payment_process_queue",
        "compensate_queue": "payment_refund_queue"
      },
      {
        "name": "confirm_order",
        "queue": "order_confirm_queue",
        "compensate_queue": "order_cancel_queue"
      }
    ],
    "retry_policy": {
      "max_retries": 3,
      "retry_delay_ms": 5000
    }
  }
}

This JSON file defines the Saga steps and their RabbitMQ queues. Each step has a queue for the main action and a queue for the compensating action if rollback is needed. The retry policy controls how many times to retry a failed step and the delay between retries.

Commands
Create the queue where the inventory reservation messages will be sent. Durable means the queue survives RabbitMQ restarts.
Terminal
rabbitmqadmin declare queue name=inventory_reserve_queue durable=true
Expected OutputExpected
Successfully declared queue 'inventory_reserve_queue'
durable=true - Ensures the queue is saved to disk and not lost on server restart
Create the queue for compensating messages to release inventory if the saga needs to roll back.
Terminal
rabbitmqadmin declare queue name=inventory_release_queue durable=true
Expected OutputExpected
Successfully declared queue 'inventory_release_queue'
durable=true - Keeps the queue persistent across RabbitMQ restarts
Create the queue for payment processing messages in the saga.
Terminal
rabbitmqadmin declare queue name=payment_process_queue durable=true
Expected OutputExpected
Successfully declared queue 'payment_process_queue'
durable=true - Ensures message durability for payment processing
Create the queue for payment refund messages to undo payment if needed.
Terminal
rabbitmqadmin declare queue name=payment_refund_queue durable=true
Expected OutputExpected
Successfully declared queue 'payment_refund_queue'
durable=true - Keeps refund messages safe on server restart
Create the queue for order confirmation messages after successful payment and inventory reservation.
Terminal
rabbitmqadmin declare queue name=order_confirm_queue durable=true
Expected OutputExpected
Successfully declared queue 'order_confirm_queue'
durable=true - Ensures order confirmation messages persist
Create the queue for order cancellation messages to undo order confirmation if rollback is needed.
Terminal
rabbitmqadmin declare queue name=order_cancel_queue durable=true
Expected OutputExpected
Successfully declared queue 'order_cancel_queue'
durable=true - Keeps cancellation messages persistent
Key Concept

If you remember nothing else from this pattern, remember: break a big task into small steps with undo actions to keep distributed systems consistent.

Common Mistakes
Not creating compensating queues for rollback actions
Without compensating queues, the system cannot undo partial work, causing inconsistent data.
Always define and create queues for both forward and compensating steps in the saga.
Using non-durable queues for critical saga messages
Non-durable queues lose messages if RabbitMQ restarts, risking lost transactions.
Declare all saga queues as durable to ensure message persistence.
Not implementing retry logic for failed steps
Without retries, transient errors cause saga failure and inconsistent state.
Implement retry policies with limits and delays to handle temporary failures gracefully.
Summary
Declare durable RabbitMQ queues for each saga step and its compensating action.
Send messages to these queues to perform and undo each step in the distributed transaction.
Use retry policies to handle temporary failures and keep the system consistent.