Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Server - does [SELECT] lock [UPDATE]?

I have a complex select query and a huge table.

I'm running this select statement, meanwhile an Update statement arrives and tries to update the table.

IMHO - update requires an exclusive lock - so the update statement will have to wait till the select command is finished.

  1. Am I right ?

  2. what can I do in order to: execute the complex select, and also let the update command run (currently I don't care about dirty data)

like image 391
Royi Namir Avatar asked Aug 06 '12 13:08

Royi Namir


People also ask

Does update query lock table?

Think of it this way -- It locks every row it had to look at. No index on the column -- It had to check every row, so all rows are locked. That effectively locks the entire table. UNIQUE index on the column -- Only one row need be touched, hence, locked.

Does SELECT statement lock table SQL Server?

SELECT statements get a shared lock on the entire table. Other statements get exclusive locks on the entire table, which are released when the transaction commits. SELECT statements get shared locks on a range of rows. UPDATE and DELETE statements get exclusive locks on a range of rows.

Does SELECT query lock?

Yes it does take a shared lock on the rows that it reads by default (it also takes an Intent Shared lock on all the pages of the clustered index that it will read), this is done to prevent dirty reads.

What is update lock in SQL Server?

An UPDATE lock is a read lock which means "I intend to update this row/page/table". Readers are not blocked by this lock, but only one process can hold an UPDATE lock on a resource. please simulate a scenario which show where update lock play a key role because we know sql server place a lock when update data.


2 Answers

Yes - to a degree.

How long a SELECT holds on to a shared lock is depending on the isolation level of the transaction:

  • READ UNCOMMITTED - no shared lock is acquired at all - UPDATE is not blocked
  • READ COMMITTED - shared lock is acquired just for the duration of reading the data - UPDATE might be blocked for a very short period of time
  • REPEATABLE READ and SERIALIZABLE - shared lock is acquired and held on to until the end of the transaction - UPDATE is blocked until the SELECT transaction ends

Technically, the UPDATE statement first gets an UPDATE lock - which is compatible with a shared lock (as used by the SELECT) - for the duration of the time while it's reading the current values of the rows to be updated.

Once that's done, the Update lock is escalated to an exclusive lock for the new data to be written to the table.

like image 136
marc_s Avatar answered Sep 28 '22 04:09

marc_s


When you run the two statements concurrently (a SELECT and an UPDATE) the actual behavior will be basically random. This is because neither of the operations is instantaneous. To simplify, consider your table a list and SELECT is traversing this list, looking at one row at a time. UPDATE is also trying to update one or more rows. When the UPDATE is trying to update a row behind the SELECT then nothing happens (no blocking) because the SELECT has already progressed past the UPDATE point. If the UPDATE is trying to update the row at which SELECT is looking right now then the UPDATE will have to wait for SELECT to move on, which will happen very very very fast and the UPDATE will unblock and succeed, while the SELECT is moving ahead. But if the UPDATE is updating a row ahead of the SELECT then the update will succeed and, later, SELECT will eventually reach exactly this row and will stop, blocked. Now SELECT has to wait until the transaction that did the UPDATE commits.

This is the simplified story. The real life is much more complicated. The SELECT can have multiple read points (parallel plans). Both the SELECT and the UPDATE are subject to choosing an access path, meaning use one or more secondary indexes to locate the rows. Complex queries may contain operators that cause multiple lookups into a table (eg. joins). Both the SELECT and the UPDATE can do bookmark lookups to fetch BLOB data, which changes significantly the locking behavior. Cardinality estimation may cause the SELECT to run at a high granularity lock mode (eg. table level Shared lock). The UPDATE can trigger lock escalation, and the escalation can fail or succeed. Choosing different access paths can lead to deadlock. False lock contention can occur due to hash collisions. There are just about one myriad variables that have a say in this. And I didn't even mention higher isolation levels (repeatable read, serializable).

Perhaps you should use SNAPSHOT isolation and stop worrying about this issue?

like image 36
Remus Rusanu Avatar answered Sep 28 '22 05:09

Remus Rusanu