تولید نرم افزار با الگو

وبلاگ شخصی ابراهیم خانی

۳ مطلب با موضوع «الگوهای برنامه های سازمانی» ثبت شده است

pessimistic concurrency

همانطور که در پست قبلی اشاره شد، یکی از روش های دستکاری مسائل مربوط به همزمانی [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

 

 

۰ نظر موافقین ۱ مخالفین ۰
ابراهیم خانی

optimistic concurrency

یکی از مشکلات مربوط به همزمانی که در پست قبلی به آن اشاره شد، lost update است. امکان به وجود آمدن این وضعیت در یک تراکنش سیستمی در sql server امکان پذیر نیست. اما هنگامی که نوبت به تراکنش های کسب و کار [1] می رسد داستان متفاوت می شود. از آنجایی که حین انجام یک تراکنش کسب و کار امکان انجام چند تراکنش سیستم وجود دارد، تظمینی برای جلوگیری از lost update وجود ندارد. یکی از راه های غلبه بر این مشکل استفاده از الگوی optimistic lock است.

ایده اصلی این الگو استفاده از row versioning است.  به عبارت دیگر برای هر سطر هنگام انجام عملیات مربوط به نوشتن یک version هم در پایگاه داده ثبت می شود. برای این version در sql server از نوع داده ی row version استفاده می شود. این نوع داده یک عدد افزایشی است که با هر عمل نوشتن در پایگاده داده افزایش می یابد.  برای بررسی lost update در هر عمل نوشتن، version سطری که در قرار است در پایگاه داده نوشته شود با version ای که پایگاه داده وجود دارد مقایسه می شود که عدم تطابق آنها نشانه تغییر در سطر مد نظر است. باید دقت کرد که optimistic lock قادر به شناسایی dirty read نیست (در پست های قبلی توضیح داده شد).

برای غلبه بر مشکل dirty read  با استفاده از روش خوشبینانه [2] می توان از سطح جداسازی [3] read committed snapshot استفاده کرد. این سطح جداسازی پیاده سازی optimistic از read committed است. در این پیاده سازی مشکل dirty read نخواهیم داشت. اساس روش های خوش بینانه عدم نیاز به قفل برای خواننده است. در این سطح جداسازی، در طول تراکنش مربوط به نوشتن، مقدار قدیمی یک ستون در version store که در tempdb ذخیره می شود نگهداری می شود. در خلال این تراکنش، هنگامی که یک خواننده قصد خواندن مقدار این ستون را دارد، مقدار اولیه این ستون را از version store می خواند.



[1] - Business transaction
[2] - Optimistic
[3] - Isolation level
۰ نظر موافقین ۱ مخالفین ۰
ابراهیم خانی

offline concurrency

از ویژگی های عمومی برنامه های سازمانی [1] دسترسی چندین کاربر به طور همزمان به آنها است. از آنجایی که در این دسترسی ها، حالت قبلی (که در پایگاه داده قرار دارد) مورد ارجاع قرار می گیرد، با چالش دسترسی چند process و یا thread به داده مشترک رو به رو خواهیم شد و این تعریف همزمانی [2] است. در نگاه اول به نظر می رسد استفاده از تراکنش ها [3] حلال همه مشکلات باشد. اما در بسیاری از موارد قرار دادن تراکنش کسب و کار [4] در یک تراکنش سیستم امکان پذیر نیست. در اینگونه از موارد الگوهایی برای دستکاری همزمانی وجود دارد که Fowler آنها را offline concurrency می نامد.

به طور کلی در پایگاه داده دو دسته از فعالیت ها وجود دارد که می بایست نسبت به یکدیگر همگام شوند. این دو دسته نویسنده ها[5] و خواننده ها[6] هستند. نویسنده ها دستورات select هستند که حالت پایگاه داده را تغییر نمی دهند و خواننده ها دستوراتdelete ,update ,insert  که باعث تغییر در حالت پایگاه داده می شوند.  دسترسی همزمان این فعالیت ها به یک داده در پایگاه داده مشکلاتی را به همراه خواهد داشت. این مشکلات عبارتند از :

Lost update : این مشکل زمانی به وجود می آید که دو تراکنش نویسنده به طور همزمان یک سطر داده را تغییر دهند. در این صورت تغییرات تراکنش اول توسط تراکنش دوم بازنویسی [7] خواهد شد.

Dirty read : این مشکل زمانی به وجود می آید که یک تراکنش خواننده حین اجرای یک تراکنش نویسنده، سطر داده ای که تراکنش نویسنده نوشته است را بخواند.

Non repeatable read : این مشکل زمانی به وجود می آید که در فاصله بین دو عمل خواندن در یک تراکنش خواننده، یک تراکنش نویسنده اقدام به تغییر سطر مورد نظر نماید. در نتیجه تراکنش خواننده مقادیر متفاوتی را برای سطر مورد نظر خواهد خواند.

Phantom read : این مشکل زمانی به وجود می آید که در فاصله بین دو عمل خواندن در یک تراکنش خواننده، یک تراکنش نویسنده اقدام به تغییر در جدول مورد نظر نماید. در نتیجه تعداد سطرهایی که تراکنش خواننده در دفعات مختلف خواهد خواند، متفاوت خواهد بود.

در پست های آتی الگوهای offline concurrency مورد بررسی قرار خواهد گرفت.



[1] - Enterprise
[2] - Concurrency
[3] - Transaction
[4] - Business transaction
[5] - Writer
[6] - Reader
[7] - Override 
۰ نظر موافقین ۰ مخالفین ۰
ابراهیم خانی