Comment pouvons-nous vérifier quels verrous de base de données sont appliqués sur quelles lignes par rapport à un lot de requêtes?
Un outil mettant en évidence le verrouillage au niveau des lignes de la table en temps réel?
DB: SQL Server 2005
Pour ajouter aux autres réponses, _sp_lock
_ peut également être utilisé pour vider des informations de verrouillage complet sur tous les processus en cours d'exécution. La sortie peut être écrasante, mais si vous voulez savoir exactement ce qui est verrouillé, c'est un outil précieux à exécuter. Je l’utilise habituellement avec _sp_who2
_ pour rapidement identifier les problèmes de verrouillage.
Il existe plusieurs versions différentes de procédures "plus conviviales" _sp_lock
_ disponibles en ligne, en fonction de la version de SQL Server en question.
Dans votre cas, pour SQL Server 2005, _sp_lock
_ est toujours disponible, mais obsolète. Il est donc recommandé d'utiliser la vue sys.dm_tran_locks
pour ce genre de chose. Vous pouvez trouver un exemple montrant comment "lancer votre propre" fonction sp_lock ici .
Cela ne vous indique pas exactement quelles lignes sont verrouillées, mais cela peut vous être utile.
Vous pouvez vérifier quelles instructions sont bloquées en lançant ceci:
select cmd,* from sys.sysprocesses
where blocked > 0
Il vous indiquera également ce que chaque bloc attend. Vous pouvez donc remonter tout cela en haut pour voir quelle instruction a provoqué le premier bloc qui a provoqué les autres blocs.
Modifier ajouter un commentaire de @ MikeBlandford :
La colonne bloquée indique le spid du processus de blocage. Vous pouvez exécuter kill {spid} pour résoudre ce problème.
Vous pouvez trouver les verrous actuels sur votre table en suivant la requête.
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');
Voir sys.dm_tran_locks
Si plusieurs instances du même type request_owner_type existent, la colonne request_owner_id est utilisée distinguer chaque instance. Pour les transactions distribuées, les colonnes request_owner_type et request_owner_guid affichent les différentes informations d'entité.
Par exemple, Session S1 possède un verrou partagé sur Table1; et la transaction T1, qui s'exécute sous la session S1, possède également un verrou partagé sur Table1. Dans ce cas, la colonne resource_description renvoyée par sys.dm_tran_locks montrera deux instances de la même ressource. La colonne request_owner_type affiche une instance en tant que session et l'autre en tant que transaction. De plus, la colonne resource_owner_id aura des valeurs différentes.
J'utilise une vue de gestion dynamique (DMV) pour capturer les verrous, ainsi que l'identifiant d'objet ou l'identificateur de partition de l'élément verrouillé.
(DOIT passer à la base de données que vous voulez observer pour obtenir 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;
Vous pouvez également utiliser la procédure stockée intégrée sp_who2
pour obtenir les processus bloqués et bloquants actuels sur une instance SQL Server. En règle générale, vous l'exécuteriez parallèlement à une instance de SQL Profiler pour rechercher un processus de blocage et consulter la commande la plus récente émise par spid dans l'éditeur de profil.
Vous pouvez trouver des détails via le script ci-dessous.
-- List all Locks of the Current Database
SELECT TL.resource_type AS ResType
,TL.resource_description AS ResDescr
,TL.request_mode AS ReqMode
,TL.request_type AS ReqType
,TL.request_status AS ReqStatus
,TL.request_owner_type AS ReqOwnerType
,TAT.[name] AS TransName
,TAT.transaction_begin_time AS TransBegin
,DATEDIFF(ss, TAT.transaction_begin_time, GETDATE()) AS TransDura
,ES.session_id AS S_Id
,ES.login_name AS LoginName
,COALESCE(OBJ.name, PAROBJ.name) AS ObjectName
,PARIDX.name AS IndexName
,ES.Host_name AS HostName
,ES.program_name AS ProgramName
FROM sys.dm_tran_locks AS TL
INNER JOIN sys.dm_exec_sessions AS ES
ON TL.request_session_id = ES.session_id
LEFT JOIN sys.dm_tran_active_transactions AS TAT
ON TL.request_owner_id = TAT.transaction_id
AND TL.request_owner_type = 'TRANSACTION'
LEFT JOIN sys.objects AS OBJ
ON TL.resource_associated_entity_id = OBJ.object_id
AND TL.resource_type = 'OBJECT'
LEFT JOIN sys.partitions AS PAR
ON TL.resource_associated_entity_id = PAR.hobt_id
AND TL.resource_type IN ('PAGE', 'KEY', 'RID', 'HOBT')
LEFT JOIN sys.objects AS PAROBJ
ON PAR.object_id = PAROBJ.object_id
LEFT JOIN sys.indexes AS PARIDX
ON PAR.object_id = PARIDX.object_id
AND PAR.index_id = PARIDX.index_id
WHERE TL.resource_database_id = DB_ID()
AND ES.session_id <> @@Spid -- Exclude "my" session
-- optional filter
AND TL.request_mode <> 'S' -- Exclude simple shared locks
ORDER BY TL.resource_type
,TL.request_mode
,TL.request_type
,TL.request_status
,ObjectName
,ES.login_name;
--TSQL commands
SELECT
db_name(rsc_dbid) AS 'DATABASE_NAME',
case rsc_type when 1 then 'null'
when 2 then 'DATABASE'
WHEN 3 THEN 'FILE'
WHEN 4 THEN 'INDEX'
WHEN 5 THEN 'TABLE'
WHEN 6 THEN 'PAGE'
WHEN 7 THEN 'KEY'
WHEN 8 THEN 'EXTEND'
WHEN 9 THEN 'RID ( ROW ID)'
WHEN 10 THEN 'APPLICATION' end AS 'REQUEST_TYPE',
CASE req_ownertype WHEN 1 THEN 'TRANSACTION'
WHEN 2 THEN 'CURSOR'
WHEN 3 THEN 'SESSION'
WHEN 4 THEN 'ExSESSION' END AS 'REQUEST_OWNERTYPE',
OBJECT_NAME(rsc_objid ,rsc_dbid) AS 'OBJECT_NAME',
PROCESS.HOSTNAME ,
PROCESS.program_name ,
PROCESS.nt_domain ,
PROCESS.nt_username ,
PROCESS.program_name ,
SQLTEXT.text
FROM sys.syslockinfo LOCK JOIN
sys.sysprocesses PROCESS
ON LOCK.req_spid = PROCESS.spid
CROSS APPLY sys.dm_exec_sql_text(PROCESS.SQL_HANDLE) SQLTEXT
where 1=1
and db_name(rsc_dbid) = db_name()
--Lock on a specific object
SELECT *
FROM sys.dm_tran_locks
WHERE resource_database_id = DB_ID()
AND resource_associated_entity_id = object_id('Specific Table');