Sunday 30 June 2024

What is Saga Pattern in java? Explain with example.


The Saga Pattern is a design pattern used to manage and coordinate long-running transactions in a distributed system. It ensures that a series of actions are completed successfully or compensating actions are taken to undo the work done, maintaining consistency in the system. This pattern is particularly useful in microservices architectures where a single business process may span multiple services.

Example: Online Order Processing

Imagine an online shopping application where a user places an order for multiple items. The process involves several steps across different microservices:

1. Order Service: Receives the order request.
2. Inventory Service: Checks and reserves the items in stock.
3. Payment Service: Processes the payment.
4. Shipping Service: Arranges the shipping of the items.

If any of these steps fail, the system should be able to roll back the previous actions to maintain consistency.

Here’s how the Saga Pattern can be applied to handle this scenario:

1. Start the Saga: The Order Service initiates the order process and starts the saga.
2. Execute Steps with Compensating Actions:
    - Inventory Service: Reserves items. If this fails, there’s no need for compensation as nothing has been done yet.
    - Payment Service: Charges the customer. If this fails, the Inventory Service releases the reserved items.
    - Shipping Service: Arranges the shipping. If this fails, the Payment Service refunds the payment, and the Inventory Service releases the reserved items.
3. Compensation Logic: Each service must have compensating actions to undo its work if a subsequent service fails.


Ex:

import java.util.ArrayList;
import java.util.List;
// Saga Step Interface
interface SagaStep {
    void execute();
    void compensate();
}
// Order Service
class OrderService implements SagaStep {
    public void execute() {
        System.out.println("Order received and validated.");
    }
    
    public void compensate() {
        System.out.println("Order cancelled.");
    }
}
// Inventory Service
class InventoryService implements SagaStep {
    public void execute() {
        System.out.println("Items reserved.");
    }
    
    public void compensate() {
        System.out.println("Items reservation cancelled.");
    }
}
// Payment Service
class PaymentService implements SagaStep {
    public void execute() {
        System.out.println("Payment processed.");
    }
    
    public void compensate() {
        System.out.println("Payment refunded.");
    }
}
// Shipping Service
class ShippingService implements SagaStep {
    public void execute() {
        System.out.println("Shipping arranged.");
    }
    
    public void compensate() {
        System.out.println("Shipping cancelled.");
    }
}
// Saga Coordinator
class SagaCoordinator {
    private List<SagaStep> steps = new ArrayList<>();
    
    public void addStep(SagaStep step) {
        steps.add(step);
    }
    
    public void execute() {
        for (SagaStep step : steps) {
            try {
                step.execute();
            } catch (Exception e) {
                // Compensate in reverse order
                for (int i = steps.indexOf(step); i >= 0; i--) {
                    steps.get(i).compensate();
                }
                break;
            }
        }
    }
}
// Main Application
public class SagaPatternExample {
    public static void main(String[] args) {
        SagaCoordinator saga = new SagaCoordinator();
        saga.addStep(new OrderService());
        saga.addStep(new InventoryService());
        saga.addStep(new PaymentService());
        saga.addStep(new ShippingService());
        
        saga.execute();
    }
}




1. SagaStep Interface: Defines the methods for executing and compensating a step.
2. Order, Inventory, Payment, Shipping Services: Implement the `SagaStep` interface, providing logic for execution and compensation.
3. SagaCoordinator: Manages the sequence of steps, executing each and handling compensation if an error occurs.
4. Main Application: Creates a `SagaCoordinator`, adds the steps, and starts the saga execution.

No comments:

Post a Comment