Blocking: وقتی یک تراکنش پشت تراکنش دیگر منتظر میماند
متوسط
۱۱ دقیقه مطالعه
در درس قبل دیدیم وقتی Session A روی یک ردیف قفل انحصاری دارد، Session B باید منتظر بماند. این وضعیت انتظار، اسم دارد: Blocking. خودِ Blocking یک باگ نیست — بخش طبیعی و لازم هر پایگاهدادهی چندکاربره است. مشکل از جایی شروع میشود که این انتظار، خیلی طول بکشد.
سناریوی کامل Blocking
Session A
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100000 WHERE id = 1;
-- کار دیگری هم انجام میدهد (مثلاً ارتباط با یک API خارجی)...
COMMIT; ← بالاخره اینجا اجرا میشود
Session B
UPDATE accounts SET balance = balance + 50000 WHERE id = 1;
-- Blocked: منتظر رهاشدن قفل ردیف id=1
-- همچنان منتظر...
-- تازه الان، بعد از COMMIT شدن Session A، اجرا میشود
اگر Session A به هر دلیلی — کدنویسی ضعیف، فراخوانی یک سرویس خارجی کند وسط تراکنش، یا فراموشکردن COMMIT — دیر تمام شود، Session B (و هر Session دیگری که منتظر همان ردیف است) هم به همان اندازه معطل میماند. این دقیقاً همان چیزی است که کاربران بهعنوان «سایت/اپلیکیشن قفل کرده» تجربه میکنند.
Blocking در برابر Deadlock — یک تفاوت مهم
Blocking یعنی یک تراکنش منتظر دیگری میماند — با گذشت زمان، معمولاً خودش حل میشود (وقتی تراکنش اول COMMIT/ROLLBACK کند). اما Deadlock (بنبست) حالت خاص و خطرناکتری است: دو تراکنش، هرکدام منتظر منبعی هستند که در قفل آنیکی است — یعنی هیچکدام هرگز خودشبهخود آزاد نمیشود. SQL Server این حالت را تشخیص میدهد و یکی از دو تراکنش را بهعنوان «قربانی» انتخاب و با خطا لغو میکند تا دیگری بتواند ادامه دهد.
چطور Blocking را کاهش دهیم
- تراکنشها را کوتاه نگه دار: هیچوقت وسط یک تراکنش، منتظر یک فراخوانی شبکهای یا کاربر نمان.
- ایندکس مناسب داشته باش: پرسوجوی بدون ایندکس مناسب، ممکن است مجبور شود ردیفهای بیشتری را قفل کند (موضوع فصل ۱۰).
- سطح ایزولهسازی مناسب انتخاب کن: بعضی سطوح ایزولهسازی، قفل کمتری میگیرند — موضوع دقیق درس بعدی.
- ابزار تشخیص: در SQL Server واقعی،
sp_who2یا Activity Monitor نشان میدهند کدام Session، کدام Session دیگر را مسدود کرده.
جمعبندی این درس
- Blocking یعنی یک تراکنش منتظر رهاشدن قفل تراکنش دیگر بماند — پدیدهای طبیعی، نه یک باگ.
- مشکل واقعی وقتی شروع میشود که تراکنش نگهدارندهی قفل، بیشازحد طول بکشد.
- Deadlock حالت خاصتری است: دو تراکنش منتظر یکدیگرند و SQL Server باید یکی را قربانی کند.
- کوتاه نگهداشتن تراکنشها، مؤثرترین راه کاهش Blocking است.
در آخرین درس این فصل، سراغ سطوح ایزولهسازی میرویم: چطور میتوان با تنظیم دقیقتر، بین سرعت و امنیت داده در برابر تداخل همزمان، تعادل برقرار کرد.