Deadlock extended event

and continue. The 1205 (deadlock victim) error records information about the type of resources

and continue. The 1205 (deadlock victim) error records information about the type of resources

involved in a deadlock.

By default, the Database Engine chooses the transaction running the transaction that is the

least expensive to roll back as the deadlock victim. Alternatively, a user can specify the priority

of sessions in a deadlock situation using the

statement.

can be set to

,

, or

, or alternatively can be set to any

integer value in the range from -10 to 10. In certain cases, the Database Engine might opt to

alter the deadlock priority for a short duration to achieve better concurrency.

The deadlock priority defaults to

, or 0. If two sessions have different deadlock priorities,

the transaction on the session with the lower priority is chosen as the deadlock victim. If both

sessions have the same deadlock priority, the transaction that is least expensive to roll back is

chosen. If sessions involved in the deadlock cycle have the same deadlock priority and the

same cost, a victim is chosen randomly. A task that is rolling back can’t be chosen as a

deadlock victim.

When working with common language runtime (CLR), the deadlock monitor automatically

detects deadlocks for synchronization resources (monitors, reader/writer lock, and thread join)

accessed inside managed procedures. However, the deadlock is resolved by throwing an

exception in the procedure that was selected to be the deadlock victim. It’s important to

understand that the exception doesn’t automatically release resources currently owned by the

victim; the resources must be explicitly released. Consistent with exception behavior, the

exception used to identify a deadlock victim can be caught and dismissed.

To view deadlock information, the Database Engine provides monitoring tools in the form of

the

extended event, two trace flags, and the deadlock graph event in SQL

Profiler.

The

extended event is the recommended method for capturing deadlock

information.

In SQL Server 2012 (11.x) and later versions, the

extended event should

be used instead of the deadlock graph event class in SQL Trace or SQL Profiler.

The

system_health

event session captures

events by default. These events

contain the deadlock graph. Because the

session is enabled by default, you

don’t need to configure a separate event session to capture deadlock information.

The deadlock graph captured typically has three distinct nodes:. The deadlock victim process identifier. Information on all the processes involved in the deadlock. Information about the resources involved in the deadlock.

You can view the

target data of the

session in Management Studio.

If any

events occurred, Management Studio presents a graphical

depiction of the tasks and resources involved in a deadlock, as seen in the following example:

The following query can view all deadlock events captured by the

target of the

session:

Here’s the result set.

The following example shows an example of the output from the

column:

XML

SET DEADLOCK_PRIORITY

DEADLOCK_PRIORITY

LOW

NORMAL

HIGH

NORMAL

xml_deadlock_report

xml_deadlock_report

xml_deadlock_report

xml_deadlock_report

system_health

victim-list
process-list
resource-list

event_file

system_health

xml_deadlock_report

ring_buffer

system_health

SELECT xdr.value(
'@timestamp'
,
'datetime'
)
AS deadlock_time,
xdr.query(
'.'
)
AS event_data
FROM (
SELECT
CAST ([target_data]
AS
XML
)
AS target_data
FROM sys.dm_xe_session_targets
AS xt
INNER
JOIN sys.dm_xe_sessions
AS xs
ON xs.address = xt.event_session_address
WHERE xs.name = N
'system_health'
AND xt.target_name = N
'ring_buffer'
)
AS
XML_Data
CROSS
APPLY
Target_Data.nodes(
'RingBufferTarget/event[@name="xml_deadlock_report"]'
)
AS
XEventData(xdr)
ORDER
BY deadlock_time
DESC
;

event_data

<event name
=
"xml_deadlock_report"
package
=
"sqlserver"
timestamp
=
"2022-02-
18T08:26:24.698Z"
>
<data name
=
"xml_report"
>
<type name
=
"xml"
package
=
"package0"
/>
<value>
<deadlock>
<victim-list>
<victimProcess id
=
"process27b9b0b9848"
/>
</victim-list>
<process-list>
<process id
=
"process27b9b0b9848"
taskpriority
=
"0"
logused
=
"0"
waitresource
=
"KEY: 5:72057594214350848 (1a39e6095155)"
waittime
=
"1631"
ownerId
=
"11088595"
transactionname
=
"SELECT"
lasttranstarted
=
"2022-02-
18T00:26:23.073"
XDES
=
"0x27b9f79fac0"
lockMode
=
"S"
schedulerid
=
"9"
kpid
=
"15336"
status
=
"suspended"
spid
=
"62"
sbid
=
"0"
ecid
=
"0"
priority
=
"0"
trancount
=
"0"
lastbatchstarted
=
"2022-02-18T00:26:22.893"
lastbatchcompleted
=
"2022-02-
18T00:26:22.890"
lastattention
=
"1900-01-01T00:00:00.890"
clientapp
=
"SQLCMD"
hostname
=
"ContosoServer"
hostpid
=
"7908"
loginname
=
"CONTOSO\user"
isolationlevel
=
"read committed (2)"
xactid
=
"11088595"
currentdb
=
"5"
lockTimeout
=
"4294967295"
clientoption1
=
"538968096"
clientoption2
=
"128056"
>
<executionStack>
<frame procname
=
"AdventureWorks2022.dbo.p1"
line
=
"3"
stmtstart
=
"78"
stmtend
=
"180"
sqlhandle
=
"0x0300050020766505ca3e07008ba80000010000000000000000000000000000000000000
00000000000000000"
>
SELECT c2, c3 FROM t1 WHERE c2 BETWEEN @p1 AND @p1+
</frame>
<frame procname
=
"adhoc"
line
=
"4"
stmtstart
=
"82"
stmtend
=
"98"
sqlhandle
=
"0x020000006263ec01ebb919c335024a072a2699958d3fcce600000000000000000000000
00000000000000000"
>
unknown
</frame>
</executionStack>
<inputbuf>
SET NOCOUNT ON
WHILE (1=1)
BEGIN
EXEC p1 4
END
</inputbuf>
</process>
<process id
=
"process27b9ee33c28"
taskpriority
=
"0"
logused
=
"252"
waitresource
=
"KEY: 5:72057594214416384 (e5b3d7e750dd)"
waittime
=
"1631"
ownerId
=
"11088593"
transactionname
=
"UPDATE"
lasttranstarted
=
"2022-02-
18T00:26:23.073"
XDES
=
"0x27ba15a4490"
lockMode
=
"X"
schedulerid
=
"6"
kpid
=
"5584"
status
=
"suspended"
spid
=
"58"
sbid
=
"0"
ecid
=
"0"
priority
=
"0"
trancount
=
"2"
lastbatchstarted
=
"2022-02-18T00:26:22.890"
lastbatchcompleted
=
"2022-02-
18T00:26:22.890"
lastattention
=
"1900-01-01T00:00:00.890"
clientapp
=
"SQLCMD"
hostname
=
"ContosoServer"
hostpid
=
"15316"
loginname
=
"CONTOSO\user"
isolationlevel
=
"read committed (2)"
xactid
=
"11088593"
currentdb
=
"5"
lockTimeout
=
"4294967295"
clientoption1
=
"538968096"
clientoption2
=
"128056"
>
<executionStack>
<frame procname
=
"AdventureWorks2022.dbo.p2"
line
=
"3"
stmtstart
=
"76"
stmtend
=
"150"
sqlhandle
=
"0x03000500599a5906ce3e07008ba80000010000000000000000000000000000000000000
00000000000000000"
>
UPDATE t1 SET c2 = c2+1 WHERE c1 = @p
</frame>
<frame procname
=
"adhoc"
line
=
"4"
stmtstart
=
"82"
stmtend
=
"98"
sqlhandle
=
"0x02000000008fe521e5fb1099410048c5743ff7da04b2047b00000000000000000000000
00000000000000000"
>
unknown
</frame>
</executionStack>
<inputbuf>
SET NOCOUNT ON
WHILE (1=1)
BEGIN
EXEC p2 4
END
</inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid
=
"72057594214350848"
dbid
=
"5"
objectname
=
"AdventureWorks2022.dbo.t1"
indexname
=
"cidx"
id
=
"lock27b9dd26a00"
mode
=
"X"
associatedObjectId
=
"72057594214350848"
>
<owner-list>
<owner id
=
"process27b9ee33c28"
mode
=
"X"
/>
</owner-list>
<waiter-list>
<waiter id
=
"process27b9b0b9848"
mode
=
"S"
requestType
=
"wait"
/>
</waiter-list>
</keylock>
<keylock hobtid
=
"72057594214416384"
dbid
=
"5"
objectname
=
"AdventureWorks2022.dbo.t1"
indexname
=
"idx1"
id
=
"lock27afa392600"
mode
=
"S"
associatedObjectId
=
"72057594214416384"
>
<owner-list>
<owner id
=
"process27b9b0b9848"
mode
=
"S"
/>
</owner-list>
<waiter-list>
<waiter id
=
"process27b9ee33c28"
mode
=
"X"
requestType
=
"wait"
/>
</waiter-list>
</keylock>
</resource-list>
</deadlock>
</value>
</data>
</event>