J'ai un gros rapport que j'exécute sur le serveur SQL. L'exécution prend plusieurs minutes. Je ne veux pas que les utilisateurs cliquent deux fois sur Exécuter. Étant donné que j'encapsule toute la procédure dans une transaction, comment puis-je vérifier si la table est verrouillée par une transaction? Si c'est le cas, je voudrais retourner un message d'erreur disant "génération de rapport, veuillez réessayer dans quelques minutes".
Comment cela peut-il être accompli?
Mieux encore, considérez sp_getapplock
qui est conçu pour cela. Ou utiliser SET LOCK_TIMEOUT
Sinon, vous devrez faire quelque chose avec sys.dm_tran_locks
que j'utiliserais uniquement pour les trucs DBA: pas pour la concurrence définie par l'utilisateur.
Vous pouvez utiliser le sys.dm_tran_locks
vue, qui renvoie des informations sur les ressources du gestionnaire de verrous actuellement actives.
Essaye ça
SELECT
SessionID = s.Session_id,
resource_type,
DatabaseName = DB_NAME(resource_database_id),
request_mode,
request_type,
login_time,
Host_name,
program_name,
client_interface_name,
login_name,
nt_domain,
nt_user_name,
s.status,
last_request_start_time,
last_request_end_time,
s.logical_reads,
s.reads,
request_status,
request_owner_type,
objectid,
dbid,
a.number,
a.encrypted ,
a.blocking_session_id,
a.text
FROM
sys.dm_tran_locks l
JOIN sys.dm_exec_sessions s ON l.request_session_id = s.session_id
LEFT JOIN
(
SELECT *
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(sql_handle)
) a ON s.session_id = a.session_id
WHERE
s.session_id > 50
Si vous vérifiez si un verrou est appliqué sur une table ou non, essayez la requête ci-dessous.
SELECT resource_type, resource_associated_entity_id,
request_status, request_mode,request_session_id,
resource_description, o.object_id, o.name, o.type_desc
FROM sys.dm_tran_locks l, sys.objects o
WHERE l.resource_associated_entity_id = o.object_id
and resource_database_id = DB_ID()
sys.dm_tran_locks contient les informations de verrouillage des sessions
Si vous souhaitez savoir qu'une table spécifique est verrouillée ou non, vous pouvez utiliser la requête suivante
SELECT
*
from
sys.dm_tran_locks
where
resource_associated_entity_id = object_id('schemaname.tablename')
si vous souhaitez trouver le nom de connexion de l'utilisateur et la requête en cours d'exécution
SELECT
DB_NAME(resource_database_id)
, s.original_login_name
, s.status
, s.program_name
, s.Host_name
, (select text from sys.dm_exec_sql_text(exrequests.sql_handle))
,*
from
sys.dm_tran_locks dbl
JOIN sys.dm_exec_sessions s ON dbl.request_session_id = s.session_id
INNER JOIN sys.dm_exec_requests exrequests on dbl.request_session_id = exrequests.session_id
where
DB_NAME(dbl.resource_database_id) = 'dbname'
Pour plus d'informations requête de verrouillage
Plus d'informations sur sys.dm_tran_locks