The before code tries to manually rollback on failure, which is error-prone and scattered. The after code uses a Saga class to coordinate steps and compensations cleanly, ensuring consistent rollback if any step fails.
### Before: No Saga, naive distributed transaction
class OrderService:
def create_order(self, order):
inventory_result = InventoryService.reserve(order.items)
if not inventory_result:
return False
payment_result = PaymentService.charge(order.payment_info)
if not payment_result:
InventoryService.release(order.items) # manual rollback
return False
ShippingService.schedule(order)
return True
### After: Saga pattern with compensating transactions
class OrderSaga:
def execute(self, order):
try:
InventoryService.reserve(order.items)
PaymentService.charge(order.payment_info)
ShippingService.schedule(order)
except Exception as e:
self.compensate(order)
raise e
def compensate(self, order):
ShippingService.cancel(order)
PaymentService.refund(order.payment_info)
InventoryService.release(order.items)