دربارهٔ این فصل
یادداشتِ همراه نوارتا حالا به این فکر کردهاید که وقتی چند نفر همزمان روی یک حساب بانکی یا یک موجودی کار میکنند، چطور پایگاه داده جلوی قاطی شدن دادهها را میگیرد؟ واقعیت این است که در دنیای سیستمهای داده، شبکهها قطع میشوند، سختافزارها از کار میافتند و درخواستهای همزمان میتوانند کل سیستم را به هم بریزند.
در کتاب «طراحی برنامههای دادهگرا» اثر «مارتین کلپمن»، فصل هفتم به بحث مهم تراکنشها (Transactions) اختصاص دارد و بررسی میکند که چطور این مکانیسم، برنامهنویسی را با پنهان کردن خطاهای جزئی و مسائل همزمانی سادهتر میکند.
برای درک بهتر رفتار تراکنشها، مفهوم ACID مخفف اتمی بودن، سازگاری، ایزولاسیون و دوام مطرح میشود که البته تعاریف تجاری آن گاهی مبهم است. ویژگی Atomicity (اتمی بودن) تضمین میکند که اگر خطایی وسط چند عملیات رخ دهد، کل کار لغو میشود و تغییرات ثبتشده برمیگردند تا برنامهنویس نگران خطاهای جزئی نباشد. مثال بارز آن انتقال وجه است که اگر مرحلهای شکست بخورد، کل تراکنش متوقف میشود.
مشکل بعدی، تداخل تراکنشهای همزمان است که برای حل آن از Isolation (ایزولاسیون) استفاده میشود. سطوح مختلف ایزولاسیون از خواندن متناوب Read Committed شروع میشوند که از کثیفخوانی جلوگیری میکند، اما گاهی به پدیدههایی مثل Lost Update (بهروزرسانی ازدسترفته) منجر میشود. وقتی دو کاربر همزمان روی یک مقدار کار میکنند و یکی تغییر دیگری را بازنویسی میکند، بهروزرسانی ازدسترفته رخ میدهد که پایگاههای داده با قفلگذاری یا عملگرهای اتمی با آن مقابله میکنند.
حتی در سطوح پیشرفتهتر مثل Snapshot Isolation (ایزولاسیون اسنپشات)، که با مکانیزم Multi-Version Concurrency Control (کنترل همزمانی چندنسخهای) به هر تراکنش یک نمای ثابت از دادهها را میدهد، مسائل پیچیدهتری مثل Write Skew (انحراف نوشتن) ممکن است اتفاق بیفتد. انحراف نوشتن زمانی رخ میدهد که دو تراکنش بر اساس یک پیشفرض درست تصمیم میگیرند دادهای را تغییر دهند، اما تداخل همزمان باعث نقض قوانین کسبوکار میشود؛ مثل نمونهٔ پزشکان کشیک که همزمان درخواست مرخصی میدهند.
برای رسیدن به بالاترین سطح اطمینان و جلوگیری از تمام این خطاهای همزمانی، Serializability (سریالپذیری) به کار میرود تا نتیجهٔ اجرای همزمان تراکنشها دقیقاً شبیه اجرای پشتسرهم آنها باشد. سیستمها برای پیادهسازی این سطح از الگوریتمهایی مثل Two-Phase Locking (قفلگذاری دو مرحلهای) یا روشهای خوشبینانه مثل Serializable Snapshot Isolation (ایزولاسیون اسنپشات سریالپذیر) استفاده میکنند که هر کدام هزینهها و مزایای خاص خود را دارند.
پیشنهاد من به عنوان میزبان این است که در طراحی سیستمهای خود، تا جایی که امکان دارد از تراکنشهای کوتاه و مشخص استفاده کنید و پیش از انتخاب سطح ایزولاسیون، دقیقاً بررسی کنید که برنامهٔ شما به چه سطح از سازگاری نیاز دارد.
امیدوارم این بخش از نگاهی به کتاب طراحی برنامههای دادهگرا برایتان مفید بوده باشد و در برنامهسیستمهای بعدیتان به کار بیاید.