我有一张看起来像这样的桌子
Create Table Items(
[Id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[UniqueCol] [nvarchar](20) NOT NULL,
[Col] int NOT NULL
)
ALTER TABLE Items ADD CONSTRAINT UN_UniqueCol UNIQUE(UniqueCol)
我在 sql server 2008 中有一个看起来像这样的存储过程。
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION
if not exists(select * from Items where UniqueCol=uniqueval)
begin
insert into Items (UniqueCol, Col) values (uniqueval, val)
end
select * from Items where UniqueCol = uniqueval
COMMIT TRANSACTION
编辑:此合并正常工作
MERGE INTO Items as Target USING (VALUES(uniqueval)) as source (UniqueCol)
on (source.UniqueCol = Target.UniqueCol)
WHEN MATCHED THEN
update set col = val
WHEN NOT MATCHED BY Target THEN
insert (UniqueCol, col) VALUES (uniqueval, val);
我在 asp.net mvc 中运行一个网站,该网站经常遇到此过程。我在存储过程中执行此操作的原因是,我认为这是处理当两件事情试图同时插入相同的事情时发生的并发问题的最简单的地方。
最后的选择以某种方式将值返回给我在 asp.net mvc 中的模型。我不确定这是否是正确的方法,但是当我尝试从网络服务器调用存储过程时它可以工作
这个存储过程被非常频繁地调用,并且可能同时使用 2 个相同的东西。唯一键可防止存储错误数据,但我希望不必提交并捕获唯一键异常以在并发插入发生时处理它们。我可以在不影响性能的情况下锁定表吗?
我假设这会锁定项目,以便 2 个请求无法尝试同时插入其中,(并导致重复的 id)并且他们无法尝试将相同的值插入表中两次(2 行UniqueCol=唯一)
我这样做不正确吗?我只是尝试并行调用这个存储过程几次,一次给我一个错误,说存在重复的 PK 违规。
似乎设置事务隔离级别并不意味着以这种方式锁定表。有人可以解释它的含义以及为此类事务锁定表的正确方法吗?