2011-10-18 57 views
1

我有一个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

您不会因为读取已提交事务隔离级别而进行脏读操作。读取未提交只能获得脏读。 – 2011-10-19 00:43:17

+0

不好意思说 - 做更新和插入原子。我如何结合他们 – Ryan

回答

1

你需要去所有的方式高达SERIALIZABLE

REPEATABLE READ如果该行不存在,那么两个UPDATE语句可以同时运行而不会相互阻塞并继续进行插入。在SERIALIZABLE下,该行将被阻止的范围。

但是,您还应该考虑将隔离级别保留为默认read committed并在keyA,keyB上添加一个唯一约束,以便任何尝试插入副本都会失败并返回错误。