سطوح ایزولهسازی تراکنش (Isolation Levels)
حرف «I» در ACID مخفف Isolation (ایزولهسازی) بود، اما نگفتیم دقیقاً «ایزوله بودن» چقدر باید باشد. جواب این است: قابل تنظیم است. SQL Server چند سطح ایزولهسازی ارائه میدهد که هرکدام، تعادل متفاوتی بین «صحت داده» و «سرعت/همزمانی» برقرار میکنند. سطح بالاتر یعنی ایمنتر اما کندتر (قفل بیشتر)؛ سطح پایینتر یعنی سریعتر اما در معرض خطر دیدن دادهی نادرست.
سه پدیدهی ناخواسته که باید بشناسیم
| پدیده | توضیح |
|---|---|
| Dirty Read | خواندن دادهای که تراکنش دیگر هنوز COMMIT نکرده — ممکن است لحظهای بعد ROLLBACK شود و دادهی خواندهشده اصلاً واقعی نبوده باشد. |
| Non-Repeatable Read | یک تراکنش، یک ردیف را دوبار میخواند و بین این دو بار، مقدار آن توسط تراکنش دیگری تغییر و COMMIT شده — نتیجهی دو خواندن فرق میکند. |
| Phantom Read | یک تراکنش، یک شرط را دوبار با SELECT ... WHERE اجرا میکند و بین این دو بار، تراکنش دیگری ردیف جدیدی اضافه/حذف کرده که در نتیجهی دوم ظاهر/ناپدید میشود. |
سطوح ایزولهسازی و پدیدههایی که اجازه میدهند
| سطح | Dirty Read | Non-Repeatable Read | Phantom Read | قفلگیری |
|---|---|---|---|---|
READ UNCOMMITTED | ممکن است رخ دهد | ممکن است رخ دهد | ممکن است رخ دهد | کمترین |
READ COMMITTED (پیشفرض SQL Server) | جلوگیری میشود | ممکن است رخ دهد | ممکن است رخ دهد | متوسط |
REPEATABLE READ | جلوگیری میشود | جلوگیری میشود | ممکن است رخ دهد | بیشتر |
SERIALIZABLE | جلوگیری میشود | جلوگیری میشود | جلوگیری میشود | بیشترین |
SNAPSHOT | جلوگیری میشود | جلوگیری میشود | جلوگیری میشود | بدون قفل خواندن (از Row Versioning استفاده میکند) |
SET TRANSACTION ISOLATION LEVEL READ COMMITTED; (یا هر سطح دیگر) قبل از BEGIN TRANSACTION تنظیم میشود.مثال بصری: چرا READ COMMITTED برای Non-Repeatable Read کافی نیست
چون Session B بین دو SELECT در Session A مقدار را تغییر داده و COMMIT کرده، Session A دو نتیجهی متفاوت برای یک ردیف واحد میبیند — این همان Non-Repeatable Read است. اگر Session A از سطح REPEATABLE READ یا بالاتر استفاده میکرد، ردیف id=1 تا پایان تراکنش A قفل میماند و Session B مجبور به انتظار میشد.
SNAPSHOT: راهحل مدرنتر
سطح SNAPSHOT (و نسخهی سبکتر آن READ COMMITTED SNAPSHOT) بهجای قفلگذاری روی دادههای در حال خواندن، از تکنیک Row Versioning استفاده میکند: هر تراکنش، یک «عکس لحظهای» (Snapshot) از داده در لحظهی شروع تراکنش میبیند، بدون اینکه مانع نوشتن دیگران شود و بدون اینکه منتظر نوشتن دیگران بماند. این سطح، Dirty/Non-Repeatable/Phantom Read را بدون قفل سنگین حذف میکند — قیمتش، مصرف بیشتر tempdb برای نگهداشتن نسخههای قدیمی ردیفهاست.
WAL دارد، اما چون همهچیز در همین صفحه و در یک اتصال واحد اجرا میشود، تفاوت سطوح ایزولهسازی را نمیتوان اینجا بهصورت زنده نشان داد — دقیقاً به همین دلیل، این درس و دو درس قبلی (قفلگذاری و Blocking) بهصورت مفهومی و با نمودار روایت شدند، نه با جعبهی اجرای زنده.جمعبندی فصل ۹
- سطح ایزولهسازی، تعادل بین صحت داده و سرعت/همزمانی را کنترل میکند.
READ COMMITTEDپیشفرض SQL Server است و فقط جلوی Dirty Read را میگیرد.REPEATABLE READوSERIALIZABLEایمنترند اما قفل بیشتری میگیرند و شانس Blocking را بالا میبرند.SNAPSHOTبا Row Versioning، ایمنی بالا را بدون قفل سنگین خواندن فراهم میکند.- در این فصل با تراکنش، ACID، قفلگذاری، Blocking و سطوح ایزولهسازی آشنا شدیم — پایهای که هر برنامهنویس SQL حرفهای باید آن را بشناسد، حتی اگر مستقیماً کدنویسی نکند.
فصل بعدی سراغ ایندکسگذاری و کارایی (Indexing & Performance) میرود — جایی که یاد میگیریم موتور پایگاهداده چطور پرسوجوها را واقعاً اجرا میکند و چطور آن را سریعتر کنیم.
تمرینهای خودآزمایی
اول خودت جواب بده، بعد پاسخ را باز کن و مقایسه کن.
۱Dirty Read چیست و کدام سطح ایزولهسازی آن را اجازه میدهد؟نمایش پاسخ
خواندن دادهای که هنوز Commit نشده؛ سطح READ UNCOMMITTED (و راهنمای NOLOCK) آن را مجاز میکند.
۲سطح ایزولهسازی پیشفرض SQL Server کدام است؟نمایش پاسخ
READ COMMITTED.