Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding out which locks that are acquired in a query on SQL Server?

I have a SQL statement from my application. I'd like to know which locks that statement acquires; how can I do that with SQL server? The statement has been involved in a deadlock, which I'm trying to analyze; I cannot reproduce the deadlock. I'm running on MS SQL Server 2005.

like image 547
Tomas Avatar asked May 07 '09 12:05

Tomas


4 Answers

You can run the statement in a transaction, but not commit the transaction. Since the locks will be held until the transaction is committed, this gives you time to inspect the locks. (Not indefinitely, but like 5 minutes by default.)

Like:

BEGIN TRANSACTION
select * from table

Then open Management Studio and check the locks. They're in Management -> Activity Monitor -> Locks by Object or Locks by Process. After you're done, run:

COMMIT TRANSACTION

to free the locks.

like image 101
Andomar Avatar answered Nov 10 '22 23:11

Andomar


I would suggest that you turn on the Deadlock Detection Trace Flags in the first instance, rather than running a Profiler Trace indefinitely.

This way, the event details will be logged to the SQL Server Error Log.

Review the following Books Online reference for details of the various trace flags. You need to use 1204 and/or 1222

http://msdn.microsoft.com/en-us/library/ms188396(SQL.90).aspx

Be sure to enable the trace flags with server scope and not just the current session. For example use:

DBCC TRACEON(1222,-1)
like image 31
John Sansom Avatar answered Nov 11 '22 00:11

John Sansom


Here's a query that will show you all active locks, who's got them, and what object they are on. I pulled this from a technet article or something years and years ago. It works on SQL 2000 and 2005 (change sysobjects to sys.objects for 2005.) Uncomment the WHERE clause if you want to restrict it to just this databse, and just the "EXCLUSIVE" locks.

select 'Locks' as Locks,
    spid, nt_username, name, hostname, loginame, waittime, open_tran,
    convert(varchar ,getdate() - last_batch, 114) as TimeSinceLastCommand,
    case req_mode
    when  0 then 'Not granted'
    when  1 then 'Schema stability'
    when  2 then 'Schema modification'
    when  3 then 'Intent shared'
    when  4 then 'Shared intent update'
    when  5 then 'Intent shared shared'
    when  6 then 'Intent exclusive'
    when  7 then 'Shared Intent Exclusive'
    when  8 then 'Shared'
    when  9 then 'Update'
    when 10 then 'Intent insert NULL'
    when 11 then 'Intent shared exclusive'
    when 12 then 'Intent update'
    when 13 then 'Intent shared-update'
    when 14 then 'Exclusive'
    when 15 then 'Bulk operation'
    else str(req_mode) end as LockMode
from master..syslockinfo
    left join sysobjects so on so.id = rsc_objid
    left join master..sysprocesses sp on sp.spid = req_spid
--where rsc_dbid = (select db_id()) and ltrim(req_mode) in (6,7,11,14) 
like image 3
Rick Avatar answered Nov 10 '22 23:11

Rick


run a trace in the profiler (pick the blank template), select the deadlock graph event, and on the new tab that appears (Events Extraction Settings), save each (check save deadlock XML events separately) in its own file. Open this file in an xml viewer and it will be easy to tell what is happening. Each process is contained, with a stack of procedure calls, etc. and all locks are in there too.

Let this trace run until the deadlock happens again, info is only recorded when a deadlock happens, so not much overhead. If it never happens again, good it is solved, if not you have captured all the info.

like image 2
KM. Avatar answered Nov 10 '22 22:11

KM.