2009-03-29 2 views

ответ

94

Чтобы добавить другие ответы, sp_lock также может использоваться для сброса полной информации о блокировке всех запущенных процессов. Выходной сигнал может быть подавляющим, но если вы хотите точно знать, что заблокировано, это будет полезно для запуска. Я обычно использую его вместе с sp_who2, чтобы быстро обнулить ошибки при блокировке.

Существует несколько различных версий «более дружественных» sp_lock процедур, доступных в Интернете, в зависимости от версии SQL Server.

В вашем случае для SQL Server 2005 sp_lock по-прежнему доступен, но устарел, поэтому теперь рекомендуется использовать вид sys.dm_tran_locks для такого рода вещей. Вы можете найти пример того, как «сворачивать свою собственную» функцию sp_lock here.

80

Это не точно показывает вам, какие строки будут заблокированы, но это может полезно для вас.

Вы можете проверить, какие заявления заблокированы работает следующим образом:

select cmd,* from sys.sysprocesses 
where blocked > 0 

Он также скажет вам, что каждый блок ждет дальше. Таким образом, вы можете проследить все это, чтобы увидеть, какой оператор вызвал первый блок, который вызвал другие блоки.

Редактировать добавить комментарий от @MikeBlandford:

Блокированный колонка указывает SPID процесса блокировки. Вы можете запустить kill {spid}, чтобы исправить это.

+7

Блокированный столбец указывает на блокировку процесса блокировки. Вы можете запустить kill {spid}, чтобы исправить это. –

16

Вы также можете использовать встроенную хранимую процедуру sp_who2, чтобы получить блокированные и блокирующие процессы на экземпляре SQL Server. Как правило, вы запускаете это вместе с экземпляром SQL Profiler, чтобы найти процесс блокировки, и посмотрите на самую последнюю команду, которую spid выдает в профилировщике.

28

Я использую Dynamic Management View (DMV) для захвата блокировок, а также object_id или partition_id элемента, который заблокирован.

(ДОЛЖЕН перейти в базу данных вы хотите наблюдать, чтобы получить object_id)

SELECT 
    TL.resource_type, 
    TL.resource_database_id, 
    TL.resource_associated_entity_id, 
    TL.request_mode, 
    TL.request_session_id, 
    WT.blocking_session_id, 
    O.name AS [object name], 
    O.type_desc AS [object descr], 
    P.partition_id AS [partition id], 
    P.rows AS [partition/page rows], 
    AU.type_desc AS [index descr], 
    AU.container_id AS [index/page container_id] 
FROM sys.dm_tran_locks AS TL 
INNER JOIN sys.dm_os_waiting_tasks AS WT 
ON TL.lock_owner_address = WT.resource_address 
LEFT OUTER JOIN sys.objects AS O 
ON O.object_id = TL.resource_associated_entity_id 
LEFT OUTER JOIN sys.partitions AS P 
ON P.hobt_id = TL.resource_associated_entity_id 
LEFT OUTER JOIN sys.allocation_units AS AU 
ON AU.allocation_unit_id = TL.resource_associated_entity_id; 
+0

Я пытаюсь использовать этот оператор, чтобы узнать, какие объекты ждет процесс. Я ясно вижу, что один сеанс ждет другого, используя 'sp_who2' и в' sys.dm_os_waiting_task' (оба пытаются обновить одну и ту же таблицу). Но ваше утверждение не возвращает никаких строк. Есть идеи? –

18

Вы можете найти текущие замки на вашем столе, выполнив запрос.

USE yourdatabase; 
GO 

SELECT * FROM sys.dm_tran_locks 
    WHERE resource_database_id = DB_ID() 
    AND resource_associated_entity_id = OBJECT_ID(N'dbo.yourtablename'); 

См sys.dm_tran_locks

Если несколько экземпляров одного и того же request_owner_type существует, request_owner_id столбец используется для различения каждого экземпляра.Для распределенных транзакций request_owner_type и столбцы request_owner_guid будут отображать информацию о разных объектах.

Например, сессия S1 имеет общую блокировку таблицы 1; и транзакция T1, которая работает под сеансом S1, также имеет общую блокировку в таблице 1. В этом случае столбец resource_description, который возвращается sys.dm_tran_locks, отображает два экземпляра одного и того же ресурса. Столбец request_owner_type отобразит один экземпляр как сеанс, а другой - как транзакцию. Кроме того, столбец resource_owner_id будет иметь разные значения.

Смежные вопросы