![](/img/trans.png)
[英]What kind of lock is placed for SELECT statement within a transaction in SQL Server
[英]exclusive lock and shared lock for select statement - SQL Server
我无法理解 select 在排他事务中的行为方式。 请考虑以下情况 –
方案 1步骤 1.1
create table Tmp(x int)
insert into Tmp values(1)
步骤 1.2 - 会话 1
begin tran
set transaction isolation level serializable
select * from Tmp
步骤 1.3 - 会话 2
select * from Tmp
即使第一个会话还没有完成,会话 2 将能够读取 tmp 表。 我认为 Tmp 将具有排他锁,并且不应发出共享锁来选择会话 2 中的查询。而且它没有发生。 我已确保默认隔离级别为 READ COMMITED。
提前感谢您帮助我理解这种行为。
编辑:为什么我需要在排他锁中选择?
我有一个实际生成顺序值的 SP。 所以流量是 -
该 SP 由数千个实例并行执行。 如果两个实例同时执行 SP,那么它们将读取相同的值并更新 value+1。 虽然我希望每次执行都有顺序值。 我认为只有当 select 也是独占锁的一部分时才有可能。
如果您希望事务可序列化,则必须在开始最外层事务之前更改该选项。 因此,您的第一个会话不正确,并且实际上仍在读取已提交(或对该会话有效的任何其他级别)下运行。
但是即使您更正了语句的顺序,它仍然不会为普通的SELECT
语句获取排他锁。
如果您希望普通的SELECT
获得排他锁,则需要请求它:
select * from Tmp with (XLOCK)
或者你需要执行一个实际上需要排他锁的语句:
update Tmp set x = x
您的第一个会话不需要排他锁,因为它不会更改数据。 如果您的第一个(可序列化)会话已经运行完成并且回滚或提交,那么在您的第二个会话开始之前,该会话的结果仍然是相同的,因为您的第一个会话没有更改数据 - 因此“可序列化”交易的性质是正确的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.