Medium severitytimeout
SQL Server Error:
1222
What does this error mean?
SQL Server raises error 1222 when a session requests a lock on a row, page, or table, but another session already holds an incompatible lock and the configured LOCK_TIMEOUT expires before the lock becomes available. In a data-pipeline context this typically surfaces when an ADF Copy Activity, a dbt model run, or a Power BI dataset refresh tries to read or write a table that is locked by a concurrent ETL process, a long-running stored procedure, or an open transaction left behind by a failed job. The engineer sees the activity fail with 'Lock request time out period exceeded' in the ADF monitor, the SQL Server error log, or the application's connection driver output.
Common causes
- 1A long-running ETL transaction (e.g. a large MERGE or DELETE with millions of rows) holds exclusive locks on a table while a second pipeline activity tries to read or write the same table.
- 2The application or connection string has SET LOCK_TIMEOUT set to a low value (e.g. 5000 ms) that is too short for normal query durations under concurrent load.
- 3An uncommitted transaction from a failed or abandoned session holds locks indefinitely — common after an ADF activity times out but the SQL session stays open due to connection pooling.
- 4Index rebuild or reorganize operations (ALTER INDEX ... REBUILD) take schema modification locks that block all concurrent queries on the table for the duration of the operation.
- 5Escalation from row-level to table-level locks during a large scan causes a wider blocking scope than expected — queries that previously coexisted now conflict.
How to fix it
- 1Step 1: Identify the blocking chain — run: SELECT r.session_id, r.blocking_session_id, r.wait_type, r.wait_time/1000 AS wait_sec, DB_NAME(r.database_id) AS db, t.text AS sql_text FROM sys.dm_exec_requests r CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t WHERE r.blocking_session_id > 0; — this shows every blocked session, how long it has waited, and the SQL text of the blocked query.
- 2Step 2: Find the head blocker (the root session that is not itself blocked) — run: SELECT s.session_id, s.login_name, s.host_name, s.program_name, t.text AS last_sql FROM sys.dm_exec_sessions s CROSS APPLY sys.dm_exec_sql_text(s.most_recent_sql_handle) t WHERE s.session_id IN (SELECT blocking_session_id FROM sys.dm_exec_requests WHERE blocking_session_id > 0) AND s.session_id NOT IN (SELECT session_id FROM sys.dm_exec_requests WHERE blocking_session_id > 0);
- 3Step 3: If the head blocker is safe to terminate (not a critical production transaction), kill it: KILL <session_id>; — then verify the blocked sessions resume by re-running the query from Step 1.
- 4Step 4: For recurring blocking during ETL windows, add LOCK_TIMEOUT to the specific batch that needs it: SET LOCK_TIMEOUT 30000; — this gives 30 seconds instead of the default infinite wait. Do not set this globally on the server.
- 5Step 5: Reduce lock duration by breaking large transactions into smaller batches — e.g. instead of DELETE FROM staging WHERE load_date < '2026-01-01', delete in chunks of 10,000 rows using a WHILE loop with TOP(10000) and COMMIT after each batch.
- 6Step 6: Move index maintenance to off-peak hours and use ONLINE = ON where possible: ALTER INDEX idx_name ON dbo.table_name REBUILD WITH (ONLINE = ON); — this avoids schema modification locks during business hours.
- 7Step 7: Enable Read Committed Snapshot Isolation (RCSI) if readers are being blocked by writers: ALTER DATABASE YourDB SET READ_COMMITTED_SNAPSHOT ON; — this lets SELECT queries read a consistent snapshot without acquiring shared locks. Requires tempdb capacity for version store.
Example log output
Msg 1222, Level 16, State 56, Line 14
Lock request time out period exceeded.
The statement has been terminated.