ساگا (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.