This article explains how to diagnose an active deadlock on an ApsaraDB RDS for SQL Server instance, identify the sessions and resources involved, and apply fixes to prevent recurrence.
Problem description
When an application frequently reads from or writes to the same table or resource, two sessions can end up waiting on each other — each holding a lock that the other needs. SQL Server detects this cycle and terminates one of the transactions (the deadlock victim), then sends an error to the client:
Error Message: Msg 1205, Level 13, State 47, Line 1Transaction (Process ID 53) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.Prerequisites
Before you run the diagnostic queries, connect to your ApsaraDB RDS for SQL Server instance from a client tool.
Diagnose the deadlock
Use one or more of the following methods to identify which sessions are blocked and what resources they are contending for.
Method 1: Query SYS.SYSPROCESSES
Run the following SQL statement to poll the SYS.SYSPROCESSES view at a fixed interval:
WHILE 1 = 1
BEGIN
SELECT * FROM SYS.SYSPROCESSES WHERE BLOCKED <> 0;
WAITFOR DELAY '[$Time]';
END;Replace [$Time] with the polling interval. For example, use 00:00:01 to poll every second.
The following figure shows a sample output.

Key columns in the output:
| Column | Description |
|---|---|
blocked | The session ID of the session blocking the current session |
waitresource | The resource the blocked session is waiting for |
spid | The session ID of the current row |
In the example above, session 53 and session 56 are blocking each other, which indicates a deadlock.
Method 2: Join sys.dm_tran_locks and sys.dm_os_waiting_tasks
For more detail — including the exact SQL statements running in each blocked and blocking session — run the following query:
while 1=1
Begin
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 BlockingText,
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
waitfor delay '[$Time]'
EndThe following figure shows a sample output.

The output includes the following columns:
| Column | Description |
|---|---|
DBName | The database the blocked session is trying to access |
request_session_id | The session ID of the blocked session |
blocking_session_id | The session ID of the blocking session |
BlockedObjectName | The object the blocked session is accessing |
resource_type | The type of resource the blocked session is waiting for |
RequestingText | The SQL statement running in the blocked session |
BlockingText | The SQL statement running in the blocking session |
request_mode | The lock mode requested by the blocked session |
Method 3: Use SQL Server Profiler (SQL Server 2012 only)
If your instance runs SQL Server 2012, use SQL Server Profiler to capture deadlock events and generate a deadlock graph.

The following figure shows a deadlock graph.

Resolve and prevent deadlocks
After identifying the blocking sessions and their SQL statements, apply one or more of the following fixes:
Stop blocking sessions. Kill the blocking session to immediately release its lock and let the blocked session proceed.
Commit long-running transactions. Check for transactions that have been open for an extended time. Commit them as soon as possible to release their locks.
Use WITH (NOLOCK) for read-only queries. If your application can tolerate dirty reads and queries are blocked by shared locks, add the
WITH (NOLOCK)hint so the query skips lock acquisition:SELECT * FROM table WITH (NOLOCK);Access resources in a consistent order. Check the application logic to access a resource in sequence.
What's next
View deadlock history and statistics in the ApsaraDB RDS console. For more information, see View deadlock statistics.