Skip to content

RootDBA

DBA expertise: PostgreSQL, SQL Server & MySQL

Menu
  • Home
  • blog
  • PostgreSql
  • MySql
  • Sql Server
  • About AHMED – Root DBA
Menu
Deadlocks

How to Capture SQL Server Deadlocks Using Extended Events

Posted on September 9, 2025 by AHMED

Deadlocks are one of the worst scenarios a DBA will face. They happen when two sessions are fighting for resources and each one is holding a lock the other needs. At that point, the SQL Server engine will choose one session to kill — this is called the deadlock victim.

The reality is you cannot eliminate deadlocks entirely; they’re part of SQL Server’s concurrency model. The goal is to reduce their frequency and impact as much as possible.

Common causes of deadlocks include:

  • Long-running queries caused by poorly written SQL
  • Very large DDL operations affecting millions of rows
  • Incorrect or overly strict transaction isolation levels
  • Wait types tied to underlying hardware bottlenecks

How to Capture and Address Deadlocks

To troubleshoot deadlocks properly, you need to capture and analyze them. The main options are:

  1. Extended Events – log and analyze deadlocks directly.
  2. Vlad Mihalcea’s PSBlitz (PowerShell) – find and report deadlocks.
  3. sp_Blitz (Brent Ozar’s scripts) – detect and log deadlocks.
  4. Trace Flags – enable the relevant trace flag to write deadlock info into the SQL Server error log.

Do you want me to also rewrite this into a training-style step-by-step guide (like something you’d drop in a runbook for junior DBAs), or keep it more as a high-level explanation?

Capture deadlock using extended event

extended event is great way to capture deadlock , in this section we will configure deadlock to capture deadlock and capture xml type to see image of deadlock

open SSMS and under management folder expand extended event right click on session and select new Session

Screenshot 1447-03-17 at 12.31.39 AM.png

Give a  name for session then click Events

in event library type “deadlock ” , select lock_deadlock and lock_deadlock _chain and xml_deadlock_report

click “Configure” button the select all Selected events look for (sql_text , client _app_name, client_hostname ,database_name, session_id , username ) and checkmark it

Now click on Data Storage on left panel and then define where you want the logged event to be stored the click Ok

Pasted image 20250909005633.png

The Extended event is created to start the session just right click on it and select Start Session

Pasted image 20250909005708.png

To check if it working fine i have downloaded hammerdb which benchmark utility
I will use it to run meltable session “16” and then check the events session we have setup to see deadlock

Pasted image 20250909011537.png

Right click on session and select watch live data

Pasted image 20250909011911.png

You can see that there is deadlock captured

Pasted image 20250909011833.png

Select xml_deadlock_report you will get graph where It shows what are two session where competing and which session was selected as victim

Pasted image 20250909012038.png

From graph if we analyze it we can see that one session was asking exeslusive lock on object
object tbcc.dbo.order

Pasted image 20250909012347.png

hover your mouse over the right session to see the query running

Pasted image 20250909012520.png
you can also double click on xml repot to get  full query details to see what is reason for this deadlock

Pasted image 20250909012639.png

You can see the first season the victims  session was running select query on tbcc.dbo.order with hint “WITH (repeatableread)” Prevent shared lock form reading the table while this session is running

SELECT order_line.ol_i_id
            , order_line.ol_supply_w_id
            , order_line.ol_quantity
            , order_line.ol_amount
            , order_line.ol_delivery_d
            FROM dbo.order_line WITH (repeatableread)
            WHERE order_line.ol_o_id = @os_o_id
            AND order_line.ol_d_id = @os_d_id
            AND order_line.ol_w_id = @os_w_i 
            
           
EXEC ostat @os_w_id = @P1, @os_d_id = @P2, @os_c_id = @P3, @byname = @P4, @os_c_last = @P    

(@P1 int,@P2 int,@P3 int,@P4 int,@P5 char(20))EXEC ostat @os_w_id = @P1, @os_d_id = @P2, @os_c_id = @P3, @byname = @P4, @os_c_last = @P5

The other session was running the below query

INSERT dbo.orders( o_id, o_d_id, o_w_id, o_c_id, o_entry_d, o_ol_cnt, o_all_local)
            VALUES ( @o_id, @no_d_id, @no_w_id, @no_c_id, @TIMESTAMP, @no_o_ol_cnt, @no_o_all_local    
  
EXEC neword @no_w_id = @P1, @no_max_w_id = @P2, @no_d_id = @P3, @no_c_id = @P4, @no_o_ol_cnt = @P5, @TIMESTAMP = @P   
(@P1 int,@P2 int,@P3 int,@P4 int,@P5 int,@P6 datetime2)EXEC neword @no_w_id = @P1, @no_max_w_id = @P2, @no_d_id = @P3, @no_c_id = @P4, @no_o_ol_cnt = @P5, @TIMESTAMP = @P6

Root cause looks like the transaction isolation level. In other scenarios it could be a poorly written query, a one-off DDL change run outside a batch, or a hardware bottleneck. Also review wait types.

2
Visited 254 times, 1 visit(s) today
Category: deadlock Buster, Sql server

Post navigation

← Data Partition
How to install pgEdge Distributed Postgres →

1 thought on “How to Capture SQL Server Deadlocks Using Extended Events”

  1. SQLADMIN says:
    September 9, 2025 at 12:32 pm

    Great explanation, please write an article on how to tune queries to avoid deadlocks.

Comments are closed.

© 2025 RootDBA | Powered by Minimalist Blog WordPress Theme