在SQL Server中的事务中为SELECT语句放置了什么类型的锁

时间:2016-02-29 21:40:06

标签: sql sql-server transactions database-deadlocks locks

我相信SQL Server中的每个SELECT语句都会导致放置共享锁或密钥锁。但它会在交易中放置相同类型的锁吗?共享锁或密钥锁是否允许其他进程读取相同的记录?

例如,我有以下逻辑

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;

此时我的select语句仍会创建共享锁或密钥锁,还是会升级为独占锁?其他事务是否能够从table1读取记录,还是所有事务都会等到我的事务被提交,然后其他事务才能从中进行选择?

在一个应用程序中,它是否会将select语句移到事务之外,只是将插入/更新保留在一个事务中?

1 个答案:

答案 0 :(得分:8)

SELECT将始终放置共享锁 - 除非您使用WITH (NOLOCK)提示(然后将无锁),请使用READ UNCOMMITTED交易隔离级别(相同的事情),或者除非您使用WITH (XLOCK)WITH (UPDLOCK)等查询提示专门覆盖它。

共享锁允许其他读取进程也获取共享锁并读取数据 - 但它们会阻止获取独占锁(用于插入,删除,更新操作)。

在这种情况下,只选择了三行,就会有锁定升级(仅当单个事务获取的锁数超过5000时才会发生)。

根据事务隔离级别,这些共享锁将保持不同的次数。使用READ COMMITTED(默认级别),锁定在读取数据后立即释放,而在REPEATABLE READSERIALIZABLE级别,锁将保持,直到事务提交或滚动回来。