繁体   English   中英

选择语句的排他锁和共享锁 - 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。 所以流量是 -

  1. 从表中读取最大值并将值存储在变量中
  2. 更新表设置值=值+1

该 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM