我有一个执行更新的SQL语句,然后如果@@ROWCOUNT
为0,它将插入。这基本上是SQL 2008中的MERGE
。我们遇到两个线程同时在更新上失败的情况。它将尝试在表中插入两次相同的密钥。我们正在使用默认事务隔离级别Read Committed。将级别更改为可重复读取是否可以解决此问题,或者我是否必须一直使用Serializable来使其工作?这是一些代码:
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN TRAN;
UPDATE TableA
SET Duration = @duration
WHERE keyA = @ID
AND keyB = @IDB;
IF @@rowcount = 0
BEGIN
INSERT INTO TableA (keyA,keyB,Duration)
VALUES (@ID,@IDB,@duration);
END
COMMIT TRAN;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;";
答案 0 :(得分:2)
你需要一直到SERIALIZABLE
。
在REPEATABLE READ
下如果该行不存在,则两个UPDATE
语句可以同时运行而不会相互阻塞,并继续执行插入操作。在SERIALIZABLE
下,该行的范围将被阻止。
但您还应考虑将隔离级别保留为默认read committed
并在keyA,keyB
上设置唯一约束,以便插入欺骗的任何尝试都会失败并显示错误。