همانطور که در پست قبلی اشاره شد، یکی از روش های دستکاری مسائل مربوط به همزمانی [1] الگوی optimistic lock است. اگرچه این الگو [2] قادر به حل مشکل lost update است اما کشف این وضعیت تنها هنگامی صورت می گیرد که کاربر داده هایی را وارد و اقدام به بروز رسانی [3] حالت [4] کرده است. اگر ماهیت تعامل کابران با  سیستم مورد نظر به صورتی باشد که این وضعیت به کرات صورت بگیرد، استفاده از این روش باعث اتلاف وقت کاربر و منابع سیستم است. راه کار دیگر برای حل این مشکل استفاده از الگوی pessimistic lock است. در این الگو در هر تراکنش [5] روی داده ها (در سطوح مختلف بسته به شرایط) قفل ایجاد می شود. در واقع این الگو به دنبال پیشگیری مشکلات مربوط به همزمانی است درحالی که الگوی خوش بینانه رویکرد درمانی دارد.

به طور کلی در پایگاه داده ها دو دسته از فعالیت ها وجود دارد که می بایست نسبت به یکدیگر همگام شوند. این دو دسته نویسنده ها [6] و خواننده ها [7] هستند. نویسنده ها دستورات select هستند که حالت پایگاه داده را تغییر نمی دهند و خواننده ها دستوراتdelete ,update ,insert  که باعث تغییر در حالت پایگاه داده می شوند. برای انجام عملیات خواندن، sql server یک قفل به نام قفل مشترک [8] روی سطری [9] که قرار است خوانده شود ایجاد می کند. همچنین زمان نوشتن یک قفل به نام قفل انحصاری [10] روی سطری که قرار است خوانده شود ایجاد می کند. نکته حائض اهمیت ناسازگاری این دو قفل با یکدیگر است، بدین معنا که امکان انجام خواندن و نوشتن روی یک سطر به طور همزمان وجود ندارد.

در sql server مفهوم isolation level برای توصیف مدت زمانی که خواننده ها قفل مشترک را در اختیار دارند به کار می رود.  سطح جداسازی پیش فرض read committed است. مشکل این سطح نبود پایداری در خواندن [11] است. به عبارت دیگر خواندن چند باره یک سطر در یک تراکنش، خروجی های مختلفی می تواند داشته باشد. علت این مشکل آزاد شدن قفل مشترک با خوانده شدن هر سطر داده است. در این سطح جداسازی هنگامی که نویسنده در یک تراکنش قفل اختصاصی را بدست می آورد، خواننده های دیگر نمی توانند قفل مشترک برای خواندن را بدست آورند.

برای غلبه بر این مشکل از سطح جداسازی repeatable read استفاده می شود. در این سطح جداسازی تنها پس از پایان تراکنش، قفل مشترک رها می شود. در این سطح جداسازی هنگامی که خواننده ای قفل مشترک را بدست آورد، سایر نویسندگان قادر به بدست آورد قفل اختصاصی نخواهند بود (بر عکس حالت read committed)

سطح جداسازی read uncommitted به معنای خواندن بدون به دست آوردن قفل مشترک است. در این حالت در صورتی که تراکنشی که در حال به روز رسانی داده است بازگشت کند [12] و پیش از این بازگشت در حالت جداسازی read uncommitted اقدام به خواندن آن شده باشد، حالتی را خوانده ایم که در پایگاه داده وجود ندارد. به عبارت بهتر در این حالت سازگاری [13] داده ها به خطر می افتد.

سخت گیرانه ترین سطح جداسازی serializable است که برای فراهم کردن read stability و جلوگیری از phantom read است. برای فراهم کردن این سطح جدا سازی sql server از روشی به نام key range lock استفاده می کند. در این روش به ازای هر سطر که مقدار آن برای ستون خاص در یک دامنه خاص قرار می گیرد یک قفل خاص هنگام خواندن قرار داده می شود. اگر تعداد این قفل ها بیش از 5000 شود، sql server قفل را روی کل جدول قرار می دهند. به هنگام استفاده از این قفل بهتر از است که در ستون مورد نظر یک non cluster index قرار داده شود.



[1] - Concurrency
[2] - Pattern
[3] - Update
[4] - State
[5] - Transaction
[6] - Writer
[7] - Reader
[8] - Sheared lock
[9] - Row
[10] - Exclusive lock
[11] - Read stability 
[12] - Rollback
[13] - Consistency