View locks acquired during query execution (SQL Server)
is it possible to view the locks, along with the type, acquired during the execution of a query?
Yes, for determining locks,
You can use beta_lockinfo by Erland Sommarskog
beta_lockinfo
is a stored procedure that provides information about processes and the locks they hold as well their active transactions.beta_lockinfo
is designed to gather as much information about a blocking situation as possible, so that you can instantly find the culprit and kill the blocking process if the situation is desperate. Then you can sit back and analyse the output frombeta_lockinfo
to understand how the blocking situation arose and figure out what actions to take to prevent the situation from reoccurring. The output frombeta_lockinfo
shows all active process as well as passive processes with locks, which objects they lock, what command they last submitted and which statement they are executing. You also get the query plans for the current statements. Normally, you runbeta_lockinfo
to look at the output directly, but there is also an archive mode where the data is saved to table. This is not the least useful, if you want someone to send you the output frombeta_lockinfo
at a site you don't have access to yourself.Another method is to use sp_whoIsActive by Adam Machanic with
@get_locks = 1
EXEC sp_WhoIsActive @filter = '', @filter_type = 'session', @not_filter = '', @not_filter_type = 'session', @show_own_spid = 0, @show_system_spids = 0, @show_sleeping_spids = 1, @get_full_inner_text = 0, @get_plans = 1, @get_outer_command = 1, @get_transaction_info = 0, @get_task_info = 1, @get_locks = 1, ----------> 1 = ON (get lock info); 0 = OFF @get_avg_time = 0, @get_additional_info = 0, @find_block_leaders = 0, @delta_interval = 0, @output_column_list = '[dd%][session_id][sql_text][sql_command][login_name][wait_info][tasks][tran_log%][cpu%][temp%][block%][reads%][writes%][context%][physical%][query_plan][locks][%]', @sort_order = '[start_time] ASC', @format_output = 1, @destination_table = '', @return_schema = 0, @schema = NULL, @help = 0
Here is how I look at locks by process/table/lock type:
SELECT
HostName,
"OS UserName",
Login,
spid,
"Database",
TableID,
"Table Name_________",
IndID,
-- [Index Name],
"Lock Type",
"Lock Mode",
Status,
-- Resource,
Count(*) AS "Lock Count"
FROM (
SELECT
Convert(VarChar(30), RTRIM(P.HostName)) AS HostName,
Convert(VarChar(30), RTRIM(P.nt_UserName)) AS "OS UserName",
Convert(VarChar(30), Suser_SName(p.sid)) AS Login,
Convert(SmallInt, req_spid) AS spid,
Convert(VarChar(30), DB_Name(rsc_dbid)) AS "Database",
rsc_objid AS TableID,
Convert(VarChar(30), Object_Name(rsc_objid, rsc_dbid))
AS [Table Name_________],
rsc_indid AS IndID,
CASE SubString (lock_type.name, 1, 4)
When '' Then 'None'
When 'DB' Then 'Database'
When 'FIL' Then 'File'
When 'IDX' Then 'Index'
When 'TAB' Then 'Table'
When 'PAG' Then 'Page'
When 'KEY' Then 'Key'
When 'EXT' Then 'Extent'
When 'RID' Then 'Row ID'
When 'APP' Then 'Application'
Else SubString (lock_type.name, 1, 4)
END AS "Lock Type",
Case SubString (lock_mode.name, 1, 12)
When NULL Then 'N/A'
When 'Sch-S' Then 'SCHEMA (Stability)'--'SCHEMA stability lock'
When 'Sch-M' Then 'SCHEMA (Modification)'--'SCHEMA modification lock'
When 'S' Then 'SHARED'--'SHARED Lock acquisition'
When 'U' Then 'UPDATE'--'UPDATE lock acquisition'
When 'X' Then 'EXCLUSIVE'--'EXCLUSIVE lock granted'
When 'IS' Then 'SHARED (Intent)'--'INTENT for SHARED lock'
When 'IU' Then 'UPDATE (Intent)'--'INTENT for UPDATE lock'
When 'IX' Then 'EXCLUSIVE (Intent)'--'INTENT for EXCLUSIVE lock'
When 'SIU' Then 'SHARED (Intent UPDATE)'--'SHARED lock with INTENT for UPDATE'
When 'SIX' Then 'SHARED (Intent EXCLUSIVE)'--'SHARED lock with INTENT for EXCLUSIVE'
When 'UIX' Then 'UPDATE'--'UPDATE lock with INTENT for EXCLUSIVE'
When 'BU' Then 'UPDATE (BULK)'--'BULK UPDATE lock'
Else SubString (lock_mode.name, 1, 12)
END AS "Lock Mode",
SubString(lock_status.name, 1, 5) AS Status,
SubString (rsc_text, 1, 16) AS Resource
FROM
Master..SysLockInfo S
JOIN Master..spt_values lock_type on S.rsc_type = lock_type.number
JOIN Master..spt_values lock_status on S.req_status = lock_status.number
JOIN Master..spt_values lock_mode on S.req_mode = lock_mode.number -1
JOIN Master..SysProcesses P on S.req_spid = P.spid
WHERE
lock_type.type = 'LR'
AND lock_status.type = 'LS'
AND lock_mode.type = 'L'
AND DB_Name(rsc_dbid) NOT IN ('master', 'msdb', 'model')
) AS X
WHERE TableID > 0
GROUP BY
HostName,
"OS UserName",
Login,
spid,
"Database",
TableID,
"Table Name_________",
IndID,
"Lock Type",
"Lock Mode",
Status
ORDER BY
spid, "Database", "Table Name_________", "Lock Type", Login
You can view acquired locks history in "Messages" tab after running this: DBCC TRACEON(1200, 3604, -1) But BEWARE, it is enabling those trace flags GLOBALLY, so do not forget to turn them off as soon as you do not need them.