sql-server

9 Пост

oracle

8 Пост

postgresql

11 Пост

my-sql

2 Пост

common-sql

2 Пост

News

5 Новости

What Is Lock Escalation?

When a transaction acquires too many row/page locks, Microsoft SQL Server may automatically convert them into a table lock.

Example:

  • 500,000 row locks
    → escalated into
  • 1 table lock

Purpose:

  • Reduce lock memory usage
  • Reduce lock manager overhead

Why SQL Server Needs It

Historically SQL Server relies heavily on:

  • shared locks for reads
  • exclusive locks for writes
  • lock tracking structures in memory

Without escalation:

  • millions of locks
  • huge lock manager overhead
  • memory pressure
  • slower concurrency management

So escalation is partly a scalability protection mechanism.


Why Oracle Corporation Oracle Database Usually Doesn’t Need It

Oracle architecture is fundamentally different:

  • readers use MVCC via undo
  • reads do not place shared row locks
  • only modified rows are locked

Oracle therefore tracks far fewer locks.

Even very large reads usually:

  • do not block writers
  • do not require massive lock structures

So table-level escalation is generally unnecessary.


Why PostgreSQL Global Development Group PostgreSQL Also Avoids It

PostgreSQL uses MVCC tuple versioning:

  • readers don’t lock rows for normal SELECT
  • row versions stored directly in table pages
  • no central lock explosion like classic lock-based engines

Result:

  • no traditional lock escalation mechanism

Important Nuance

Modern SQL Server is much more MVCC-capable now:

  • Read Committed Snapshot Isolation (RCSI)
  • Snapshot Isolation

But internally it still maintains the classic lock manager architecture, so lock escalation still exists.

In Microsoft SQL Server you can control lock escalation at the table level using:

 
ALTER TABLE table_name
SET (LOCK_ESCALATION = AUTO);
 

Possible values:

Option Meaning
TABLE Escalate to table lock (default)
AUTO Partition-level escalation when possible
DISABLE Try to prevent escalation

Examples:

Default behavior

 
ALTER TABLE sales_big
SET (LOCK_ESCALATION = TABLE);
 

Partition-aware escalation

Useful for partitioned tables:

 
ALTER TABLE sales_big
SET (LOCK_ESCALATION = AUTO);
 

Instead of locking the whole table, SQL Server may lock only one partition.


Disable escalation

 
ALTER TABLE sales_big
SET (LOCK_ESCALATION = DISABLE);
 

Important:

  • this does not fully guarantee escalation never happens
  • under severe memory pressure SQL Server can still escalate

Check current setting

 
SELECT name,
lock_escalation_desc
FROM sys.tables
WHERE name = 'sales_big';
 

Possible results:

  • TABLE
  • AUTO
  • DISABLE

Database-level behavior

SQL Server also has internal thresholds:

  • ~5000 locks on one object may trigger escalation
  • memory pressure can trigger it earlier

Trace flags sometimes used:

 
DBCC TRACEON (1211, -1);
 

or

 
DBCC TRACEON (1224, -1);
 

But these are dangerous in production because disabling escalation globally can:

  • exhaust lock memory
  • increase CPU overhead
  • destabilize server under heavy concurrency

Usually table-level configuration is safer.


Important Practical Note

Disabling escalation is rarely the real solution.

Usually better solutions are:

  • batching large updates/deletes
  • proper indexing
  • shorter transactions
  • partitioning
  • snapshot isolation/RCSI

Example batching:

 
WHILE 1=1
BEGIN
DELETE TOP (10000)
FROM big_table
WHERE create_date < '2024-01-01';

IF @@ROWCOUNT = 0
BREAK;
END
 

This avoids accumulating millions of locks.