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