在 SQL 服务器的事务中为 SELECT 语句放置了什么样的锁
What kind of lock is placed for SELECT statement within a transaction in SQL Server
我相信 SQL 服务器中的每个 SELECT
语句都会导致放置共享锁或密钥锁。但是它会在事务中放置相同类型的锁吗? Shared 或 Key 锁是否允许其他进程读取相同的记录?
例如我有以下逻辑
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 从中读取记录?
在一个应用程序中,将 select 语句移到事务之外并只在一个事务中保留 insert/update 是否会造成影响?
A SELECT
将始终放置共享锁 - 除非您使用 WITH (NOLOCK)
提示(然后 不会放置锁 ),使用 READ UNCOMMITTED
事务隔离级别(同样的事情),或者除非您使用 WITH (XLOCK)
或 WITH (UPDLOCK)
.
等查询提示专门覆盖它
共享锁允许其他读取进程也获取共享锁并读取数据 - 但它们会阻止获取独占锁(用于插入、删除、更新操作)。
在这种情况下,仅选择三行,将无锁升级(仅当单个事务获取超过 5000 个锁时才会发生)。
根据事务隔离级别,这些共享锁将被持有不同的时间。使用READ COMMITTED
,默认级别,在读取数据后立即释放锁,而使用REPEATABLE READ
或SERIALIZABLE
级别,锁将一直保持到事务提交或滚动返回。
我相信 SQL 服务器中的每个 SELECT
语句都会导致放置共享锁或密钥锁。但是它会在事务中放置相同类型的锁吗? Shared 或 Key 锁是否允许其他进程读取相同的记录?
例如我有以下逻辑
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 从中读取记录?
在一个应用程序中,将 select 语句移到事务之外并只在一个事务中保留 insert/update 是否会造成影响?
A SELECT
将始终放置共享锁 - 除非您使用 WITH (NOLOCK)
提示(然后 不会放置锁 ),使用 READ UNCOMMITTED
事务隔离级别(同样的事情),或者除非您使用 WITH (XLOCK)
或 WITH (UPDLOCK)
.
共享锁允许其他读取进程也获取共享锁并读取数据 - 但它们会阻止获取独占锁(用于插入、删除、更新操作)。
在这种情况下,仅选择三行,将无锁升级(仅当单个事务获取超过 5000 个锁时才会发生)。
根据事务隔离级别,这些共享锁将被持有不同的时间。使用READ COMMITTED
,默认级别,在读取数据后立即释放锁,而使用REPEATABLE READ
或SERIALIZABLE
级别,锁将一直保持到事务提交或滚动返回。