همونطور که میدونید پایگاه داده ها برا حفظ استاندارد های مشخص از ACID (خودتون از اینجا بخونین) پیروی میکنن. در راستای همین موضوع برای حفظ یکپارچگی ، سطوح ایزوله سازی پایگاه داده مشخص میکنه میزان حفظ و تمامیت یک تراکنش در مقابل تراکنش های دیگه چقدر باشه . برای درک بهتر این موضوع بهتره که دیدگاه عمیق تری نسبت به isolation و سطوح مختلفش داشته باشیم .
بصورت کلی منشا اهمیت مبحث Database Isolation به چند وضعیت و سناریوی مشخص بر میگرده که بصورت زیر تعریف میشن ( به هر وضعیت یه صفت فاجعه میدم تا بترسین و با تمرکز بالاتری بخونینش ☢️ ):
☠️ فاجعه اول Dirty Read:
این وضعیت زمانی رخ میده که یه transaction داده ای که هنوز commit نشده رو میخونه . برای درک این حالت transaction 1 رو درنظر بگیریم که یک سطر رو update میکنه و transaction 2 اطلاعاتی از همین سطر اپدیت شده رو میخونه در ادامه transaction 1 به دلایلی rollback میشه ، خب فاجعه اینجاست ☢️ !. مشکل اینه که transaction 2 داده ای رو خونده که اصلا توی database وجود نداره و یا بهتره بگیم قبلا وجود داشته !.
☠️ فاجعه دوم Non-repeatable Read :
این حالت زمانی رخ میده که یه transaction داده ی خاصی رو ۲ بار از database بخونه و هر بار با یه مقدار متفاوت روبه رو شه !. برای مثال transaction 1 داده ای رو میخونه و در ادامه transaction 2 عملیات update رو داده ها انجام میده(بستر فاجعه ایجاد شد ☢️). حالا اگه transaction 1 به خوندن دوباره داده ها نیاز داشته باشه ، داده ها تغییر کردن.
☠️ فاجعه سوم Phantom Read :
تو این وضعیت چند query یکسان اجرا میشن ولی پاسخ متفاوت دارن . برای مثال transaction 1 در راستای انجام عملیاتی ، کوئری ای رو اجرا میکنه و چند سطر رو برمیگردونه . transaction 2 در پایان عملیاتش چند سطر تولید میکنه که با transaction1 همپوشانی داره ( فاجعه اینجاس ☢️) و حالا اگه transaction 1 دوباره query مرتبط رو اجرا کنه پاسخی متفاوت دریافت میکنه .
براساس سه وضعیتی که معرفی کردیم سطوح مختلفی از ایزوله سازی و راه حل هایی برای ایجاد اونا تعریف شده که انواع مختلفی هم دارن . ما تو این مقاله به چند راهکار از دو نوع قفل و غیر قفل اشاره می کنیم تا بعد از این راهکار ها برا پیاده سازی سطوح ایزوله سازی استفاده کنیم :
راه حل اول S-lock (Shared lock) :
تو این نوع قفل اگه transaction 1 داده ای رو قفل کنه transaction 2 فقط میتونه عملیات read رو انجام بده.
راه حل دوم X-lock(Exclusive lock) :
در این نوع قفل علاوه بر عملیات write عملیات read هم قفل میشن .
راه حل سوم MVCC(Multi-Version Concurrency Control) :
این روش قفل نداره و کلا از نوع راهکار های قفلی نیست ! . و شیوه کارش به این شکله که تمامی رکوردها یه version number دارن، عملیات خوندن به صورت همزمان رو هر رکورد با بالاترین version انجام میشه و عملیات write رو یه کپی از record انجام میشه و تا زمانی که عملیات write تموم نشده کاربرا آخرین ورژن ثبت شده از record رو میبینن ولی به محض اینکه عملیات write انجام بشه version کپی رکورد مربوطه بالاتر میره و عملیات دیگه ای که به read نیاز دارن آخرین ورژن رو میخونن . با همین روال با هر update ورژن جدیدی اضافه میشه و... .
نکته 🗒️ : از معایب MVCC نسبت به قفل ها اینه که به دلیل ورژن های مختلف از رکوردها ، حجم دیتابیس به صورت خودکار افزایش پیدا میکنه( به اصطلاح پف میکنه! 💡) .
نکته 🗒️ : در مقایسه با lock ها این روش Optimization هم حساب میشه چون تأخیر ناشی از lock کردن رو حذف میکنه.
خب تا اینجا مشکل رو درک کردیم و راهکار های موجود رو توضیح دادیم . پس وقتشه که بریم سراغ ۴ سطح از ایزوله سازی تو دیتابیس و استفاده از راهکار های موجود برا پیاده سازی این سطوح . جدول زیر به صورت خلاصه این ۴ سطح رو نشون میده . تو این جدول سطوح ایزوله سازی از بالا به پایین کاهش پیدا میکنن . برای درک بهتر سطوح رو بصورت خلاصه در ادامه توضیح خواهم داد .
خلاصه ای از سطوح ایزوله سازی:
Serializable 1️⃣ : این سطح بالاترین سطح از ایزوله سازیه که گارانتی میکنه تراکنش ها sequence وار انجام بشن. درواقع اسم این روش هم از serial میاد که به معنی زنجیر واره .
Repeatable Read 2️⃣ : عملیات Read رو داده ها در طول هر تراکنش به صورتی هست که در ابتدا خونده میشه .
Read Committed 3️⃣ : تغییرات روی داده ها فقط زمانی قابل خوندن میشن که تراکنش مربوطه commit بشه.
Read Uncommitted 4️⃣ : قبل از commit شدن هر تغییراتی ، این تغییرات میتونن توسط تراکنش های دیگه خونده بشن.
و در اخر باید به این نکته توجه کرد که انتخاب سطح ایزوله سازی به نیازمندی های پروژه بستگی داره و هر چقدر سطح ایزوله سازی بالاتر باشه ، یکپارچگی بیش تر میشه . ولی خب در مقابل باعث ایجاد locktime و بار بیشتر و در نهایت Performance کمتر تو دیتابیس میشه .
نوشته ای از : عرفان علی اقدم ✌🏻.