У меня есть таблица SQL, которая внезапно не может вернуть данные, если я не включу с (nolock)
в конце, что указывает на какую-то блокировку, оставленную на моей таблице.
Я немного поэкспериментировал с sys.dm_tran_locks, чтобы определить, что на таблице действительно есть несколько блокировок, но как мне определить что их блокирует (т.е. элемент request в sys. dm_tran_locks)?
EDIT: Я знаю о sp_lock для SQL 2005, но теперь, когда этот sp устарел, AFAIK правильным способом сделать это является sys.dm_tran_locks. Я использую SQL Server 2008 R2.
Поворот сюжета!
у Вас могут быть осиротевшие распределенные транзакции, содержащие монопольные блокировки, и Вы не будете видеть их, если Ваш сценарий предположит, что существует сессия, связанная с транзакцией (нет!). Выполните сценарий ниже для идентификации этих транзакций:
;WITH ORPHANED_TRAN AS (
SELECT
dat.name,
dat.transaction_uow,
ddt.database_transaction_begin_time,
ddt.database_transaction_log_bytes_reserved,
ddt.database_transaction_log_bytes_used
FROM
sys.dm_tran_database_transactions ddt,
sys.dm_tran_active_transactions dat,
sys.dm_tran_locks dtl
WHERE
ddt.transaction_id = dat.transaction_id AND
dat.transaction_id = dtl.request_owner_id AND
dtl.request_session_id = -2 AND
dtl.request_mode = 'X'
)
SELECT DISTINCT * FROM ORPHANED_TRAN
, Как только Вы определили транзакцию, используйте transaction_uow столбец, чтобы найти его в MSDTC и решить, прервать ли или фиксировать его. Если транзакция будет отмечена как В Сомнении (с вопросительным знаком рядом с ним), то Вы, вероятно, захотите прервать его.
можно также уничтожить Единицу работы (UOW) путем определения transaction_uow в команде KILL:
KILL '<transaction_uow>'
Ссылки:
https://www.mssqltips.com/sqlservertip/4142/how-to-kill-a-blocking-negative-spid-in-sql-server /