Vous êtes sur la page 1sur 4

SQL SERVER

Identify

Blocking, deadlocks and troubleshooting.

How deadlocks work you can run the following code in the Northwind database.
To create a deadlock you can issue commands similar to the commands below.
Step Commands

--open a query window (1) and run these commands


create table block (sno varchar (20),name varchar(20))
insert into block select '5','Saif'
go 2
insert into block select '1','Qazi'
go 2
begin tran update block set sno ='8' where name='saif'
open another query window (2) and run these commands

begin tran
begin tran update block set sno ='7'

--go back to query window (1) and run these commands


begin tran update block set name='saif'
At this point SQL Server will select one of the process as a deadlock victim and
roll back the statement
--issue this command in query window (1) to undo all of the changes

4
rollback
--go back to query window (2) and run these commands to undo changes
5
rollback
Solution
The only solution for handling deadlocks is to find the problem in your code and then
modify your processing to avoid deadlock situations. The first thing you need to do
is find the deadlock situations and then investigate the problem
Here is the script we used to identify the blocking query.

SELECT
db.name DBName,
tl.request_session_id,
wt.blocking_session_id,
OBJECT_NAME(p.OBJECT_ID) BlockedObjectName,
tl.resource_type,
h1.TEXT AS RequestingText,
h2.TEXT AS BlockingTest,
tl.request_mode
FROM sys.dm_tran_locks AS tl
INNER JOIN sys.databases db ON db.database_id = tl.resource_database_id
INNER JOIN sys.dm_os_waiting_tasks AS wt ON tl.lock_owner_address =
wt.resource_address

INNER JOIN sys.partitions AS p ON p.hobt_id =


tl.resource_associated_entity_id
INNER JOIN sys.dm_exec_connections ec1 ON ec1.session_id =
tl.request_session_id
INNER JOIN sys.dm_exec_connections ec2 ON ec2.session_id =
wt.blocking_session_id
CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2
GO

In our case, we killed the blocking_session_id after carefully looking at the BlockingText; it
was found to be not necessary at all. We killed the session using the following command:
KILL 66

There are a couple of ways of doing this.


The first approach is to turn on the trace flag to find the deadlocks. This can be done
with the following statement run in Query Analyzer.

DBCC TRACEON (1204)


When a deadlock occurs the information like the following will be captured in the SQL
Server Error Log.

SQL Profiler
To do this using SQL Profiler, you will need to capture the Lock Events Lock:Deadlock
and Lock:Deadlock Chain.

And also capture the ObjectId data column.

Server Side Trace


For a Server Side Trace the following additional information will need to collected to
capture the deadlock information.
EventNumber Event

Description

25

Lock:Deadlock

Indicates that two concurrent transactions have


deadlocked each other by trying to obtain
incompatible locks on resources the other transaction
owns.

59

Lock:Deadlock
Chain

Produced for each of the events leading up to the


deadlock.

In addition, you will also need to capture this additional column to see what objects
are part of the deadlock chain.
ColumnNumber

Column

Description

22

ObjectID

System-assigned ID of the object.

The output from our trace would show the following information:

When you have a lot of information to go through it is easier to load the data into a SQL
Server table and then query the data for the particular timeframe and SPIDs
DECLARE @lowDate AS datetime, @highDate AS datetime
SET @lowDate = '2012-07-11 20:19:17.000'
SET @highDate = '2012-07-11 20:21:18.999'
SELECT TextData, StartTime,
EndTime, SPID,
Duration,
Writes,
EventClass
FROM
TraceFile
WHERE
-- SPID IN (66) AND
(StartTime BETWEEN @lowDate AND @highDate
OR EndTime BETWEEN @lowDate AND @highDate
OR StartTime < @lowDate AND EndTime > @lowDate)
ORDER BY

StartTime

Reads,

Vous aimerez peut-être aussi