ساگا (Saga) الگویی برای هماهنگ کردن یک عملیات کسب‌وکار بین چند سرویس یا چند دیتابیس است. به جای یک تراکنش ACID سراسری، هر سرویس تراکنش محلی خودش را Commit می‌کند. اگر مرحله بعدی شکست بخورد، باید با عملیات جبرانی اثر مراحل تکمیل‌شده را تا حد ممکن اصلاح کنیم. این مسئله در معماری میکروسرویس‌ها بسیار رایج است، اما محدود به یک فریم‌ورک خاص نیست.

مثال ساگا در فروشگاه اینترنتی

مرحلهعملیات اصلیعملیات جبرانی احتمالی
۱رزرو موجودی سفارشآزاد کردن موجودی رزروشده
۲گرفتن پرداختبازپرداخت یا Void کردن پرداخت، بسته به وضعیت درگاه
۳ثبت مرسولهلغو درخواست ارسال، در صورت امکان

دو روش اجرای ساگا

در Orchestration یک هماهنگ‌کننده مرکزی، وضعیت مراحل را نگه می‌دارد و فرمان مرحله بعد را ارسال می‌کند. در Choreography هر سرویس به رویداد سرویس قبلی گوش می‌دهد و بدون هماهنگ‌کننده مرکزی پیش می‌رود. روش اول مشاهده و عیب‌یابی جریان‌های طولانی را آسان‌تر می‌کند، روش دوم وابستگی به یک هماهنگ‌کننده مشترک را کاهش می‌دهد، ولی با زیاد شدن رویدادها پیچیده می‌شود.

نمونه آموزشی از Orchestration

# Educational pseudocode: each action calls a real service API.
def place_order(order_id):
    compensated = []
    try:
        inventory.reserve(order_id)
        compensated.append(lambda: inventory.release(order_id))

        payment.charge(order_id)
        compensated.append(lambda: payment.refund(order_id))

        delivery.schedule(order_id)
        return "confirmed"
    except ServiceError:
        for compensate in reversed(compensated):
            enqueue_with_retry(compensate)  # never silently ignore errors
        return "compensation_pending"

این شبه‌کد فقط منطق تصمیم‌گیری را نمایش می‌دهد. در محیط واقعی، وضعیت ساگا و شناسه همبستگی باید پایدار ذخیره شوند، اقدام‌های جبرانی در صف پردازش شوند و پس از ری‌استارت نیز ادامه پیدا کنند. از الگوی صندوق خروجی تراکنشی برای هماهنگی ثبت داده و ارسال رویداد کمک می‌گیرند. هر مرحله باید آیدمپوتنسی باشد تا اجرای دوباره پیام باعث دوبار کسر وجه یا دوبار رزرو نشود.

Rollback با عملیات جبرانی فرق دارد

در تراکنش معمولی دیتابیس، Rollback تغییرات Commitنشده را برمی‌گرداند. در ساگا ممکن است پول قبلاً از حساب برداشت شده باشد و لازم باشد تراکنش بازپرداخت جدید ثبت کنیم. عملیات جبرانی همیشه یک Undo دقیق نیست.

برای نمونه کامل‌تر پیاده‌سازی، الگوی ساگا و برای زمینه مفهومی، سیستم توزیع‌شده، معماری رویدادمحور و رول‌بک را ببینید.

مستندات رسمی: الگوی Saga در Azure Architecture Center.