Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What kind of lock is placed for SELECT statement within a transaction in SQL Server

I believe that each SELECT statement in SQL Server will cause either a Shared or Key lock to be placed. But will it place that same type of lock when it is in a transaction? Will Shared or Key locks allow other processes to read the same records?

For example I have the following logic

Begin Trans
-- select data that is needed for the next 2 statements
SELECT * FROM table1 where id = 1000; -- Assuming this returns 10, 20, 30

insert data that was read from the first query
INSERT INTO table2 (a,b,c) VALUES(10, 20, 30);

-- update table 3 with data found in the first query
UPDATE table3
SET d = 10,
   e = 20,
   f = 30;

COMMIT;

At this point will my select statement still create a shared or key lock or will it get escalated to exclusive lock? Will other transaction be able to read records from the table1 or will all transaction wait until the my transaction is committed before others are able to select from it?

In an application does it makes since to move the select statement outside of a transaction and just keep the insert/update in one transaction?

like image 796
Junior Avatar asked Feb 29 '16 21:02

Junior


People also ask

Does SQL Server lock on SELECT?

A SELECT in SQL Server will place a shared lock on a table row - and a second SELECT would also require a shared lock, and those are compatible with one another. So no - one SELECT cannot block another SELECT .

What are transaction locks in SQL Server?

Locks are held on SQL Server resources, such as rows read or modified during a transaction, to prevent concurrent use of resources by different transactions. For example, if an exclusive (X) lock is held on a row within a table by a transaction, no other transaction can modify that row until the lock is released.

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.


1 Answers

A SELECT will always place a shared lock - unless you use the WITH (NOLOCK) hint (then no lock will be placed), use a READ UNCOMMITTED transaction isolation level (same thing), or unless you specifically override it with query hints like WITH (XLOCK) or WITH (UPDLOCK).

A shared lock allows other reading processes to also acquire a shared lock and read the data - but they prevent exclusive locks (for insert, delete, update operations) from being acquired.

In this case, with just three rows selected, there will be no lock escalation (that only happens when more than 5000 locks are being acquired by a single transaction).

Depending on the transaction isolation level, those shared locks will be held for different amounts of times. With READ COMMITTED, the default level, the locks is released immediately after the data has been read, while with REPEATABLE READ or SERIALIZABLE levels, the locks will be held until the transaction is committed or rolled back.

like image 198
marc_s Avatar answered Sep 19 '22 01:09

marc_s