Quick 30-Second Fix: Kill the Blocking Process
Had a client last week whose entire sales dashboard timed out every morning at 9 AM. Turned out a single update query on the inventory table was hogging everything. Here's the fastest way to fix it.
Open SQL Server Management Studio (SSMS) and run this command to find the blocking process:
sp_who2
Look for the column called BlkBy. If you see a SPID number there (like 64), that's the process blocking everything. Then run:
KILL 64
Replace 64 with the actual SPID you see. That kills the blocking query immediately. Your query should now run.
But wait: This only fixes the symptom. The lock storm will come back unless you fix the root cause. Move to the next section if this keeps happening.
5-Minute Moderate Fix: Find the Root Query
Killing the process is like pulling the fire alarm – it stops the chaos but doesn't fix the wiring. Let's find out what query caused the lock storm.
Run this to get more detail on the blocking:
SELECT
session_id,
blocking_session_id,
wait_type,
wait_time,
wait_resource
FROM sys.dm_exec_requests
WHERE blocking_session_id > 0
This shows you which session is blocked and which one is blocking it. The wait_resource column tells you the exact object (like a table or row) being fought over.
Now get the actual SQL text of the blocking query:
SELECT text
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle)
WHERE r.session_id = 64 -- replace with your blocking SPID
What you'll usually see is a long-running transaction that forgot to commit. Or a SELECT with WITH (TABLOCK) that's locking the whole table. Common scenario: someone ran a report that locks the entire inventory table for 2 minutes during peak hours.
Fix: Ask the developer to add WITH (READUNCOMMITTED) on reports that don't need perfect accuracy. Or use SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED at the start of the query. But be careful – this can return dirty data. For critical queries, use WITH (NOLOCK) on the table instead.
15+ Minute Advanced Fix: Stop Lock Storms for Good
If you're dealing with lock storms every week, it's time to change the architecture. Here's what I've seen work in real production environments.
Step 1: Enable Snapshot Isolation
This is the nuclear option for lock storms. It lets readers read old versions of rows while writers write. No more blocking. Run this:
ALTER DATABASE YourDatabase
SET READ_COMMITTED_SNAPSHOT ON;
This changes the default isolation level to use row versioning instead of locking. Your queries won't block each other. But it uses more tempdb space because SQL Server keeps old row versions. I've seen tempdb grow by 20% on busy systems, so make sure you have disk space.
Step 2: Find and Fix Bad Indexes
Lock storms often happen because queries are scanning whole tables instead of using indexes. Run the Missing Index DMV to see what's needed:
SELECT
migs.avg_user_impact,
migs.avg_total_user_cost,
mid.statement,
mid.equality_columns,
mid.inequality_columns,
mid.included_columns
FROM sys.dm_db_missing_index_groups mig
JOIN sys.dm_db_missing_index_group_stats migs
ON migs.group_handle = mig.index_group_handle
JOIN sys.dm_db_missing_index_details mid
ON mig.index_handle = mid.index_handle
WHERE mid.database_id = DB_ID()
ORDER BY migs.avg_total_user_cost DESC
Create any indexes that have avg_user_impact over 80%. This reduces the time a query holds locks, which reduces lock storms.
Step 3: Use Lock Timeout and Retry Logic
For applications that can't use snapshot isolation, set a lock timeout so users don't wait forever. In your application code, set:
SET LOCK_TIMEOUT 5000; -- 5 seconds
Then in your C# or Python code, catch the timeout error and retry the query after a short delay. I tell clients to use a retry pattern: try 3 times with 2-second pauses between. Most lock storms clear up in seconds.
Real-World Example
Had a logistics company whose shipping label printing would timeout every afternoon. The lock storm was caused by a single UPDATE statement that ran every 15 minutes and locked the Orders table for 30 seconds. We enabled snapshot isolation, and the problem vanished. Their tempdb grew by 15%, but they had 50GB free anyway.
When to Call for Backup
If you've tried snapshot isolation, created missing indexes, and still get lock storms, the problem might be in your application logic. Long-running transactions that hold locks across user input are a common culprit. Or you might have a deadlock chain that's hard to trace. Time to bring in a DBA who can analyze your transaction logs.