【发布时间】:2023-03-04 20:59:01
【问题描述】:
我有两个事务一个接一个地开始:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
select * from MyTable WITH (XLOCK) WHERE Id = 1
WAITFOR DELAY '00:00:10';
COMMIT TRANSACTION
第二个几乎一样(只是没有延迟和另一个id)
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
select * from MyTable WITH (XLOCK) WHERE Id = 2
COMMIT TRANSACTION
我在 ID 上有一个非唯一索引。当至少在 Id 上有一个主键时,这似乎确实可以按预期工作。
据我了解,第一个事务应该真正获得 Id = 1 的键范围锁,而另一个应该获得 id 2 的键范围锁。
显然它不会像那样工作,因为第二个事务一直卡在第一个事务完成之前。我是否遗漏了某些内容,或者我无法强制独占键范围锁定?
这是我的示例的完整创建脚本:
CREATE TABLE [dbo].[MyTable](
[Id] [bigint] NOT NULL,
CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
【问题讨论】:
-
Id是集群主键吗?什么 SQL Server 版本? -
最后一个 Sql 服务器版本(Azure 数据库),它是一个聚集的主键,但我希望它与一个更复杂的非聚集索引一起工作,包括 2 列(像
id = 1 and time > now这样的钥匙锁) -
我无法使用
Id上的主键进行复制,无论是集群还是非集群。您可以验证 Id 上的索引是否存在?不一定是PK,只要是唯一的即可。 -
我的索引不会是唯一的,它必须是吗?我可以从示例中仔细检查主索引
-
我已经仔细检查了:Id 是表上的主键,将示例从 SO 复制到 Management Studio 中并且每次都可以重现,也许还有其他东西会影响这个?也许我拥有的其他领域会影响它?
标签: sql sql-server transactions locking