我想在我的表中防止删除、插入、更新和选择的并发,所以我尝试SERIALIZABLE
在事务之前使用表,但这并没有为其他进程锁定表!如何解决?
我尝试了什么:
1- 创建 Table_1
--Create Sample Table
CREATE TABLE [dbo].[Table_1](
[Number] [bigint] NOT NULL,
[Price] [bigint] NULL,
CONSTRAINT [PK_Table_1] PRIMARY KEY CLUSTERED
(
[Number] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT [dbo].[Table_1] ([Number], [Price]) VALUES (1, 1000)
GO
INSERT [dbo].[Table_1] ([Number], [Price]) VALUES (2, 3000)
GO
INSERT [dbo].[Table_1] ([Number], [Price]) VALUES (3, 8000)
GO
2- 延迟查询会话一:
--SESSION 1
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
WAITFOR DELAY '00:00:10.000'
UPDATE Table_1 SET Price = 6000 WHERE NUMBER = 1
SELECT * FROM Table_1
COMMIT TRANSACTION;
3-查询会话二,这个查询最多等待会话一直到结束进程,但事实并非如此!:
--SESSION 2
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
SELECT * FROM Table_1
COMMIT TRANSACTION;
你的延迟是在错误的地方。
在进行任何更改之前,您在事务 1 中等待十秒钟。
事务 2 没有理由在事务 2 进行任何更改之前等待。
把延迟放在更新后,你会看到阻塞。
可序列化的隔离级别保证结果与事务以某种顺序按顺序运行一样。它不要求事务实际上以这种方式运行。
如果要防止所有并发,请使用排他表锁。有关详细信息,请参阅表上的相关问答请求 Sch-M 锁。