فرض کنید یک فروشگاه آنلاین بهطور همزمان چندین تراکنش از کاربران دریافت میکند:
- تراکنش 1: مشتری قصد دارد یک محصول خاص (مثلاً گوشی موبایل) را بخرد و تراکنش خرید خود را آغاز میکند.
- تراکنش 2: مدیر فروشگاه در حال بهروزرسانی موجودی انبار همان محصول است (مثلاً افزودن تعداد جدید به انبار).
برای این دو سناریو، دو مدل بدبینانه و خوشبینانه در دیتابیسها لحاظ شده. که هر کدام میتوانند سرعت و دقت در ثبت و واکشی اطلاعات در دیتابیس را به رخ بکشند.
یک دیتابیس پویا چطور میتواند این سرعت و دقت را داشته باشد؟
در مدل بدبینانه:
- وقتی تراکنش 2 (بهروزرسانی موجودی) آغاز میشود، قفلی روی ردیف مربوط به آن محصول در دیتابیس اعمال میشود.
- تراکنش 1 (خرید مشتری) نمیتواند ادامه دهد و باید منتظر بماند تا تراکنش 2 تکمیل شود و قفل آزاد شود.
- این انتظار ممکن است باعث تأخیر در خرید مشتری و کاهش تجربه کاربری شود.
در مدل خوشبینانه:
- تراکنش 1 و تراکنش 2 بهطور همزمان اجرا میشوند.
- مشتری میتواند خرید خود را ثبت کند، حتی اگر تراکنش بهروزرسانی موجودی هنوز در حال انجام باشد.
- در پایان، سیستم بررسی میکند که آیا خرید مشتری با موجودی واقعی تضاد دارد یا خیر. اگر تضادی وجود داشته باشد (مثلاً محصول تمام شده باشد)، تراکنش خرید مشتری باطل میشود.
در دنیای واقعی:
- در مدل بدبینانه، با وجود اطمینان از صحت دادهها، سرعت تراکنش کاهش مییابد و احتمال قفلهای بنبست وجود دارد.
- در مدل خوشبینانه، عملکرد سیستم بهبود مییابد و کاربران تجربه سریعتری دارند، اما ممکن است برخی تراکنشها در لحظه نهایی به دلیل تضاد باطل شوند.
این مثال نشان میدهد که مدل خوشبینانه برای سیستمهایی که تعاملات زیادی با مشتری دارند (مانند فروشگاههای آنلاین)، مناسبتر است، در حالی که مدل بدبینانه بیشتر برای سیستمهایی استفاده میشود که دقت دادهها در اولویت است (مانند سیستمهای مالی).وقتی تراکنشها با هم رقابت میکنند: خوشبینانه یا بدبینانه؟
پایگاههای داده مدرن، میدان نبردی برای تراکنشهای موازی هستند. هر تراکنش ممکن است بخواهد دادهها را بخواند یا بهروزرسانی کند، و این رقابت سوالات مهمی را مطرح میکند:
- اگر یک تراکنش در حال بهروزرسانی دادهها باشد، آیا تراکنش دیگری که قصد خواندن دارد باید صبر کند؟
- آیا باید دادههای قدیمی را ببیند یا اجازه داشته باشد مقدار تازه را بخواند؟
برای پاسخ به این چالشها، دو مدل همزمانی طراحی شدهاند:
- کنترل همزمانی خوشبینانه
- کنترل همزمانی بدبینانه
مدل بدبینانه:
در این رویکرد، تراکنشها برای محافظت از دادهها، قفلهایی اعمال میکنند. هر تراکنش که بخواهد دادهای را بخواند یا تغییر دهد، باید منتظر آزاد شدن قفلها باشد. این مدل اطمینان میدهد که هیچ دو تراکنشی نمیتوانند بهطور همزمان یک ردیف را تغییر دهند. اما هزینه آن کاهش سرعت و احتمال بنبست است.
مدل خوشبینانه:
این مدل فرض میکند که اکثر تراکنشها با هم تداخلی ندارند، بنابراین نیازی به قفلگذاری نیست. دو تراکنش میتوانند بهطور همزمان یک ردیف را بخوانند یا تغییر دهند. اگر در پایان، تناقضی شناسایی شود، یکی از تراکنشها باطل میشود. این مدل با حذف قفلها، عملکرد بسیار بهتری ارائه میدهد.
مقایسه در سیستمها:
- پایگاه داده Postgres بهطور پیشفرض از مدل خوشبینانه استفاده میکند، زیرا برای محیطهای پرخوانش بهینهتر است.
- SQL Server ابتدا با مدل بدبینانه طراحی شد، اما به دلیل مشکلات عملکردی، گزینهای برای استفاده از کنترل همزمانی خوشبینانه معرفی کرد که به آن "ایزوله عکس فوری متعهد خوانده شده (RCSI)" میگویند.
انتخاب مدل به نیاز سیستم بستگی دارد. اگر رقابت بالا باشد، بدبینانه؛ و اگر تراکنشها بیشتر خواندن محور باشند، خوشبینانه گزینه بهتری است.