我无法理解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,那么它们将读取相同的值并将更新值+ 1。虽然我希望每次执行都有顺序值。我认为只有当select也是独占锁的一部分时才有可能。
答案 0 :(得分:0)
如果您希望事务可序列化,则必须在开始最外层事务之前更改该选项。所以你的第一个会话是不正确的,并且仍然在read committed(或任何其他级别对该会话有效)下运行。
但是即使你更正了语句的顺序,它仍然不会获得普通SELECT
语句的独占锁。
如果您希望普通SELECT
获得排他锁,则需要提出要求:
select * from Tmp with (XLOCK)
或者你需要执行一个实际需要独占锁的语句:
update Tmp set x = x
您的第一个会话不需要独占锁定,因为它不会更改数据。如果您的第一个(可序列化)会话已经运行完成并且已经回滚或提交,那么在第二个会话开始之前,该会话的结果仍然是相同的,因为您的第一个会话没有更改数据 - 所以"可序列化"交易的性质是正确的。