Hi Friends,

I wrote a blog post on partition-level locking where I demonstrated how locks are escalated from row to partition. The blog post is here;

A few readers wrote back to me asking when does SQL Server escalate the row locks to table or partition level locks. So in this post, I will talk about SQL Server Lock escalation.

Well, the DB engine has a component called the Lock Manager, which escalates fine-grained locks (rows & page locks) to more coarse grained locks (partition or table locks) under 2 circumstances:

1. When the lock threshold is reached which as per BOL is 5000 (for a single instance of the objection in question)

2. When the memory threshold is reached for Lock Manager, even if the number of locks threshold of 5000 is not reached.

Let me quickly demonstrate this to you:

I wrote the following query:

USE AdventureWorks
GO
 
BEGINTRAN
UPDATETOP (5000) Person.Contact
SET EmailPromotion = 0

You can see I am placing 5000 ROW locks, but you when you run the sys.dm_tran_locks DMV, you can see that table lock has been acquired.

select*fromsys.dm_tran_lock

Well, this perfectly in line with BOL. However, I was playing around with the numbers and I changed the value to 4900. Before you run the modification query each time, do not forget to ROLLBACK TRAN.

ROLLBACKTRAN
 
BEGINTRAN
UPDATETOP (4900) Person.Contact
SET EmailPromotion = 0

I again ran the DMV and this time also, I saw a table lock. Probably, this time I expected 4900 ROW locks. But may be the memory threshold was reached, so I continued playing with the numbers until I found that the threshold on my system is 4707/4708; where if the number of ROW locks are 4708 or more, the DB engine escalates this to a table lock, else anything below that number is those many row locks.

So if I execute the following (ROLLBACK any earlier transaction):

BEGINTRAN
UPDATETOP (4707) Person.Contact
SET EmailPromotion = 0

And then check the DMV, you shall see those many ROW locks. You can run the following:

select resource_type,
resource_database_id,
resource_description,
resource_associated_entity_id,
request_mode,
request_type,
request_status
from sys.dm_tran_locks
where resource_database_id = DB_ID();

1_SQL_Server_2008_Lock_Escalation_explained

However, when I change the value to 4708, escalation happens. (ROLLBACK the earlier transaction)

BEGINTRAN
UPDATETOP (4708) Person.Contact
SET EmailPromotion = 0

Run the DMV again:

select resource_type,
resource_database_id,
resource_description,
resource_associated_entity_id,
request_mode,
request_type,
request_status
from sys.dm_tran_locks
where resource_database_id = DB_ID();

2_SQL_Server_2008_Lock_Escalation_explained

You can observe the table lock.

ROLLABCK the transaction to clean up.

It will interesting to see/hear your output when you run the same example on your system.

 

Data Platform Virtual Summit 2020

Subscribe to SQLServerGeeks YouTube channel. If you want more learning content in your inbox, subscribe to SQLServerGeeks Bulletin.

SQLServerGeeks YouTube | SQLServerGeeks Bulletin | SQLServerGeeks Twitter