خانه/ تراکنش‌ها/ Blocking

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 است.

در آخرین درس این فصل، سراغ سطوح ایزوله‌سازی می‌رویم: چطور می‌توان با تنظیم دقیق‌تر، بین سرعت و امنیت داده در برابر تداخل هم‌زمان، تعادل برقرار کرد.