مثالهای عملی
مثال 1: نمای پایه قفلهای لحظهای
در این سناریو هدف، گرفتن یک Snapshot خوانا از قفلهای جاری بدون اتصالهای اضافی است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
SELECT TOP (50)
request_session_id,
resource_type,
request_mode,
request_status
FROM sys.dm_tran_locks
ORDER BY request_session_id, resource_type;
| خروجی نمونه | تفسیر |
|---|
| 57 | KEY | X | GRANT | نتیجه نمایشی مثال 1؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
GRANT یعنی قفل اعطا شده و WAIT یعنی درخواست هنوز منتظر آزاد شدن منبع است. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
مثال 2: شمارش قفلها بر اساس نوع و Mode
در این سناریو هدف، کاهش هزاران ردیف خام به یک نمای تجمعی برای تشخیص الگوی غالب است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
SELECT
resource_type,
request_mode,
request_status,
COUNT_BIG(*) AS lock_count
FROM sys.dm_tran_locks
GROUP BY resource_type, request_mode, request_status
ORDER BY lock_count DESC;
| خروجی نمونه | تفسیر |
|---|
| KEY | S | GRANT | 184 | نتیجه نمایشی مثال 2؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
تعداد زیاد Lock الزاماً مشکل نیست؛ آن را همراه زمان انتظار و طول تراکنش تفسیر کنید. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
مثال 3: افزودن مشخصات نشست مالک قفل
در این سناریو هدف، تبدیل SPID ناشناس به Login و میزبان قابل پیگیری در عملیات سازمانی است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
SELECT
l.request_session_id,
s.login_name,
s.host_name,
l.resource_type,
l.request_mode,
l.request_status
FROM sys.dm_tran_locks AS l
LEFT JOIN sys.dm_exec_sessions AS s
ON s.session_id = l.request_session_id
WHERE l.request_session_id > 50;
| خروجی نمونه | تفسیر |
|---|
| 57 | app_user | WEB-02 | OBJECT | IX | GRANT | نتیجه نمایشی مثال 3؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
LEFT JOIN نشستهای داخلی یا مالکانی را که ردیف Session معمول ندارند از نتیجه حذف نمیکند. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
مثال 4: نمایش متن درخواست فعال دارای قفل
در این سناریو هدف، اتصال نوع قفل به Batch فعال برای رسیدن از نشانه به فرمان ایجادکننده است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
SELECT TOP (25)
l.request_session_id,
l.request_mode,
r.status,
st.text AS batch_text
FROM sys.dm_tran_locks AS l
JOIN sys.dm_exec_requests AS r
ON r.session_id = l.request_session_id
OUTER APPLY sys.dm_exec_sql_text(r.sql_handle) AS st
WHERE l.request_session_id > 50
ORDER BY l.request_session_id;
| خروجی نمونه | تفسیر |
|---|
| 61 | U | suspended | UPDATE dbo.Orders ... | نتیجه نمایشی مثال 4؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
ممکن است برای یک Request چند قفل وجود داشته باشد؛ برای فهرست فرمانها DISTINCT یا گروهبندی آگاهانه بهکار ببرید. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
مثال 5: فیلتر درخواستهای Lock در وضعیت انتظار
در این سناریو هدف، جداکردن درخواستهایی است که واقعاً به Lock Manager منتظرند. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
SELECT
request_session_id,
resource_database_id,
resource_type,
request_mode,
resource_description
FROM sys.dm_tran_locks
WHERE request_status = N'WAIT'
ORDER BY request_session_id;
| خروجی نمونه | تفسیر |
|---|
| 64 | 7 | KEY | X | (hash-value) | نتیجه نمایشی مثال 5؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
اگر خروجی خالی است ولی کندی وجود دارد، Waitهای I/O، حافظه، Latch یا CPU را نیز بررسی کنید. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
مثال 6: تبدیل HOBT به جدول و ایندکس
در این سناریو هدف، نگاشت قفل KEY یا HOBT به شیء قابل فهم در پایگاه داده جاری است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
SELECT DISTINCT
l.request_session_id,
OBJECT_SCHEMA_NAME(p.object_id, l.resource_database_id) AS schema_name,
OBJECT_NAME(p.object_id, l.resource_database_id) AS object_name,
i.name AS index_name,
l.request_mode,
l.request_status
FROM sys.dm_tran_locks AS l
JOIN sys.partitions AS p
ON p.hobt_id = l.resource_associated_entity_id
LEFT JOIN sys.indexes AS i
ON i.object_id = p.object_id
AND i.index_id = p.index_id
WHERE l.resource_database_id = DB_ID();
| خروجی نمونه | تفسیر |
|---|
| 57 | sales | Orders | IX_Orders_Status | X | GRANT | نتیجه نمایشی مثال 6؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
sys.partitions متعلق به Database جاری است؛ برای DBID دیگر باید Query را در همان Database اجرا کنید. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
مثال 7: اتصال قفلها به تراکنش فعال
در این سناریو هدف، یافتن زمان شروع Transactionی است که Lockها را نگه داشته است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
SELECT
l.request_session_id,
at.transaction_id,
at.name AS transaction_name,
at.transaction_begin_time,
l.resource_type,
l.request_mode
FROM sys.dm_tran_locks AS l
JOIN sys.dm_tran_session_transactions AS st
ON st.session_id = l.request_session_id
JOIN sys.dm_tran_active_transactions AS at
ON at.transaction_id = st.transaction_id
WHERE l.request_session_id > 50;
| خروجی نمونه | تفسیر |
|---|
| 57 | 982341 | user_transaction | 2026-07-22 05:12 | KEY | X | نتیجه نمایشی مثال 7؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
تراکنش قدیمیتر نامزد بررسی است، اما پیش از اقدام باید مالک کسبوکار و وضعیت Commit مشخص شود. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
مثال 8: ساخت نمای Blocked و Blocker
در این سناریو هدف، ترکیب رابطه Blocking با جزئیات Lock در یک نتیجه عملیاتی است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
SELECT
r.session_id AS blocked_session_id,
r.blocking_session_id,
r.wait_type,
r.wait_time,
l.resource_type,
l.request_mode
FROM sys.dm_exec_requests AS r
LEFT JOIN sys.dm_tran_locks AS l
ON l.request_session_id = r.session_id
AND l.request_status = N'WAIT'
WHERE r.blocking_session_id > 0;
| خروجی نمونه | تفسیر |
|---|
| 64 | 57 | LCK_M_X | 8120 | KEY | X | نتیجه نمایشی مثال 8؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
برای جلوگیری از چندبرابر شدن ردیفها، فقط Lockهای WAIT نشست Blocked را متصل کردهایم. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
مثال 9: مدیریت نام نامشخص پایگاه داده
در این سناریو هدف، نمایش خروجی مقاوم در برابر NULL ناشی از سطح دسترسی یا DBID نامعتبر است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
SELECT
request_session_id,
resource_database_id,
COALESCE(DB_NAME(resource_database_id), N'(نامشخص یا خارج از دسترس)') AS database_name,
resource_type,
request_mode
FROM sys.dm_tran_locks
WHERE request_session_id > 50;
| خروجی نمونه | تفسیر |
|---|
| 57 | 7 | SalesDb | PAGE | IX | نتیجه نمایشی مثال 9؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
NULL را با Database جاری جایگزین نکنید؛ چنین کاری میتواند تحلیل رخداد را به پایگاه اشتباه نسبت دهد. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
مثال 10: نمونهبرداری هدفمند و کمهزینه
در این سناریو هدف، نشان دادن الگوی فیلتر زودهنگام برای Runbook و ابزار مانیتورینگ است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
DECLARE @TargetDatabaseId int = DB_ID();
DECLARE @TargetSessionId smallint = 57;
SELECT
request_session_id,
resource_type,
request_mode,
request_status
FROM sys.dm_tran_locks
WHERE resource_database_id = @TargetDatabaseId
AND request_session_id = @TargetSessionId;
| خروجی نمونه | تفسیر |
|---|
| 57 | KEY | X | GRANT | نتیجه نمایشی مثال 10؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
از SELECT ستاره و ذخیره همه Snapshotها بپرهیزید؛ ستون و دوره نگهداری را بر اساس سؤال عملیاتی انتخاب کنید. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
سؤالات متداول
پرسش 1: sys.dm_tran_locks دقیقاً چه مسئلهای را در SQL Server حل میکند؟
نمای مدیریتی sys.dm_tran_locks تصویری لحظهای از درخواستها و قفلهای اعطاشده یا در حال انتظار در موتور پایگاه داده ارائه میکند. هر ردیف، مالک قفل، نوع منبع، حالت قفل و وضعیت درخواست را نشان میدهد. ارزش اصلی آن زمانی آشکار میشود که سؤال عملیاتی مشخص باشد؛ مثلاً شناسایی Head Blocker، تعیین منبع انتظار یا حفظ شواهد Deadlock. خروجی باید کنار زمان رخداد و مشخصات Application نگهداری شود تا از یک Snapshot خام به پاسخ قابل اقدام برسیم.
پرسش 2: برای شروع کار با sys.dm_tran_locks چه پیشنیازی لازم است؟
ابتدا در محیط آزمایش Syntax و ستونهای نسخه نصبشده را بررسی کنید، سپس مجوز حداقلی مشاهده وضعیت را در نظر بگیرید. برای مشاهده همه نشستها معمولاً VIEW SERVER STATE و در نسخههای جدید VIEW SERVER PERFORMANCE STATE لازم است. اجرای Query با حساب Production پرقدرت راهحل مناسبی نیست و بهتر است نقش مانیتورینگ مشخص و ممیزیشده ساخته شود.
پرسش 3: استفاده از sys.dm_tran_locks چه ارزش تجاری برای سامانه پرتراکنش دارد؟
کاهش زمان تشخیص Incident، جلوگیری از تصمیم عجولانه و کوتاهشدن اختلال مستقیمترین ارزشها هستند. وقتی داده این ابزار با SLA و مالک سرویس پیوند بخورد، تیم میتواند بین کندی عادی، Blocking زیانآور و Deadlock تکرارشونده تفاوت بگذارد و هزینه توقف را کم کند.
پرسش 4: چه زمانی برای پیادهسازی مانیتورینگ sys.dm_tran_locks به مشاوره تخصصی نیاز داریم؟
اگر رخدادها تکراری، چندپایگاهدادهای، حساس به امنیت یا دارای حجم Event بالا هستند، طراحی Baseline، Retention و Runbook تخصصی مفید است. مشاوره SQL Server باید در کنار جمعآوری داده، Query Plan، تراکنش، ایندکس و رفتار کد Application را نیز بررسی کند؛ خرید ابزار بدون فرایند پاسخگویی کافی نیست.
پرسش 5: تفاوت sys.dm_tran_locks با ابزار نزدیک آن چیست؟
برخلاف sp_lock که قدیمی و محدود است، این DMV ستونهای دقیقتری درباره مالک و منبع قفل میدهد و مبنای مناسبتری برای ابزارهای مانیتورینگ است. انتخاب درست به این بستگی دارد که داده لحظهای، تاریخچه XML، مشخصات Session یا امکان اقدام مدیریتی لازم باشد. در عیبیابی حرفهای معمولاً چند منبع مکمل کنار هم استفاده میشوند، نه اینکه یک خروجی به تنهایی حقیقت کامل فرض شود.
پرسش 6: آیا میتوان پیادهسازی داشبورد یا پروژه sys.dm_tran_locks را به تیم متخصص سپرد؟
بله؛ تحویل حرفهای باید شامل تعریف نیاز، Queryهای کمهزینه، کنترل مجوز، ذخیره UTC، سیاست Retention، هشدار قابل تنظیم، داشبورد و Runbook اعتبارسنجیشده باشد. پیش از پذیرش پروژه، اثر مانیتورینگ روی Production و روش تست خطا نیز باید مستند شود.
پرسش 7: رایجترین خطا هنگام تحلیل sys.dm_tran_locks چیست؟
resource_associated_entity_id همیشه OBJECT_ID نیست؛ برای قفل KEY یا HOBT باید آن را از طریق sys.partitions تفسیر کرد. خطای دوم تصمیمگیری از روی یک Snapshot بدون Baseline است. زمان رخداد، Login، Host، Database، Transaction و Query متناظر را کنار هم قرار دهید و هر مقدار NULL یا نامشخص را صادقانه حفظ کنید.
پرسش 8: آیا Query گرفتن از sys.dm_tran_locks روی Performance اثر میگذارد؟
ابتدا بر اساس پایگاه داده، نشست یا وضعیت WAIT فیلتر کنید و فقط ستونهای لازم را بخوانید؛ نمونهبرداری بسیار پرتکرار از محیط شلوغ میتواند خودش هزینه ایجاد کند. خود مشاهده نیز رایگان نیست، بهویژه وقتی XML، Plan یا Text برای تعداد زیادی Session استخراج شود. Period نمونهبرداری، فیلتر، سقف نگهداری و مانیتور Dropped Event باید بخشی از طراحی باشد.
پرسش 9: بهترین روش استفاده Production از sys.dm_tran_locks چیست؟
پرسش عملیاتی را از قبل تعریف کنید، کمترین ستون و Scope لازم را جمع کنید، Timestamp UTC و شناسه Incident بسازید و اقدام مخرب را از جمعآوری شواهد جدا نگه دارید. Runbook باید مرحله تأیید هویت Session، اثر Rollback، تماس با مالک سرویس و معیار پایان Incident را روشن کند.
پرسش 10: sys.dm_tran_locks در کدام نسخههای SQL Server قابل استفاده است؟
جزئیات ستون، مجوز و Eventها با نسخه و Azure SQL تفاوت دارد؛ بنابراین metadata و مستندات همان نسخه باید مرجع نهایی باشد. برای مشاهده همه نشستها معمولاً VIEW SERVER STATE و در نسخههای جدید VIEW SERVER PERFORMANCE STATE لازم است. در ارتقا، Queryها را روی محیط Stage اجرا کنید و بهویژه قابلیتهای Undocumented یا Deprecated را با جایگزین مستند عوض کنید.