فصل ۵ با Saga آشنا شدی و فصل ۹ در یک سؤال گفتیم 2PC پیشفرض نیست. حالا دقیق: چرا تعهد اتمی بین چند نود مسئله سختی است، 2PC دقیقاً کجا میلنگد، TCC چیست و «linearizable» — قویترین وعده سازگاری — چه میگوید.
2PC: تعهد دو فازی
- فاز ۱: coordinator از همه participant ها میپرسد «میتوانی commit کنی؟» — هرکدام لاگ مینویسند، قفل میگیرند و رأی میدهند.
- فاز ۲: اگر همه بله گفتند commit، وگرنه abort برای همه.
- مرگبار: اگر coordinator بعد از prepare و قبل از commit بمیرد، participant ها با قفلهای گرفتهشده بلاتکلیف میمانند — blocking واقعی تا برگشت او یا مداخله دستی. به همین دلیل در microservice های پرتراکنش ممنوع است؛ جایش: دیتابیسهایی که خودشان 2PC داخلی دارند (مثل بعضی NewSQL ها).
- 3PC با فاز میانی و timeout تلاش میکند blocking را کم کند ولی تحت partition واقعی باز هم نادرست تصمیم میگیرد — در عمل کمتر استفاده میشود.
TCC: جبران در لایه کسبوکار
TCC (Try-Confirm-Cancel) همان روح Saga است ولی رسمیتر: فاز Try منابع را رزرو میکند (موجودی را freeze کن، نه کم کن)؛ Confirm رزرو را قطعی میکند؛ Cancel آزادش میکند. تفاوت با 2PC: قفل دیتابیس نمیگیرد، در لایه اپلیکیشن و با منطق دامنه کار میکند، و هر فاز idempotent و قابل retry است. مثال: رزرو سفر = Try روی پرواز + هتل + ماشین؛ همه موفق → Confirm؛ یکی شکست → Cancel بقیه.
Linearizability: قویترین وعده
به زبان ساده
تراکنش بین چند سرویس سه راه دارد: 2PC (همه قفل و رأی)، TCC (رزرو، تأیید، لغو) و Saga (کارهای جبرانپذیر)؛ و linearizability یعنی همه دنیا یک ترتیب واحد ببینند.
مثال واقعی
رزرو هتل+پرواز: TCC اول «ظرفیت را رزرو موقت» میکند؛ اگر پرواز نماند، رزرو هتل لغو میشود و اگر هر دو بود، تأیید نهایی — کسی با هتل بدون پرواز نمیماند.