Blocking is a normal part of any lock-based relational database — one session holds a lock while another waits to acquire it. It becomes a problem when the wait is long enough to slow down your application. A common cause is an application that frequently reads from or writes to the same table or resource, which can generate a large number of competing requests and degrade application performance. This topic shows you how to identify which session is causing the blocking and how to resolve it.
Identify the blocking session
Use either of the following methods to find the session holding locks.
Method 1: Query sys.sysprocesses
Run the following statement to poll sys.sysprocesses at regular intervals:
WHILE 1 = 1
BEGIN
SELECT * FROM SYS.SYSPROCESSES WHERE BLOCKED <> 0;
WAITFOR DELAY '00:00:01';
END;TheWAITFOR DELAYvalue controls the polling interval. The example uses one second (00:00:01). Adjust as needed.
The following figure shows a sample output.

Key columns in the output:
blocked: The session ID of the block header — the session holding the lock that is preventing others from proceeding.waitresource: The resource that the blocked session is waiting to acquire.
For a full list of columns, see sys.sysprocesses (Transact-SQL).
Method 2: Query sys.dm_tran_locks and sys.dm_os_waiting_tasks
For more detail — including which objects and statements are involved — run the following statement to join sys.dm_tran_locks with sys.dm_os_waiting_tasks:
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 '00:00:01';
END;The following figure shows a sample output.

The output includes the following columns:
| Column | Description |
|---|---|
DBName | The name of the database. |
request_session_id | The session ID of the blocked session. |
blocking_session_id | The session ID of the block header. |
BlockedObjectName | The objects managed by the blocked session. |
resource_type | The type of resource the session is waiting to acquire. |
RequestingText | The statement running in the blocked session. |
BlockingText | The statement running in the block header session. |
request_mode | The lock mode requested by the blocked session. |
Resolve the blocking issue
After identifying the block header session and the statements involved, take one or more of the following actions.
Kill the block header session
Run KILL <session_id> to end the session holding the lock, which immediately unblocks waiting sessions. Use this as an emergency measure and investigate the root cause afterward to prevent recurrence.
Commit long-running open transactions
Check for transactions that have been open for an extended period without being committed. Open transactions hold locks until they complete. Commit or roll back any such transactions promptly.
Use WITH (NOLOCK) for read-only queries (with caution)
If a SELECT query is blocked due to shared locks and your application can tolerate dirty reads, use the WITH (NOLOCK) query hint:
SELECT * FROM table WITH (NOLOCK);WITH (NOLOCK) skips shared lock acquisition, so the query is never blocked by writers. However, it may read uncommitted data that is later rolled back. Use this only when your application can handle inconsistent reads.
Access resources in a consistent order
If multiple transactions access the same set of tables in different sequences, they can form blocking chains or deadlocks. Review your application logic and ensure all transactions acquire locks on shared resources in the same order.
What's next
For steps to resolve blocking in emergency situations, see Resolve blocking issues on an ApsaraDB RDS for SQL Server instance.
To detect blocking before it affects your application, configure performance metrics and alert rules in the ApsaraDB RDS console. See Monitoring and alerts.
For index, query, and storage optimization strategies, see Performance optimization and diagnosis.