我有一个问题,就是使用完全相同的参数在完全相同的时间调用相同的存储过程。

存储过程的目的是获取记录(如果存在),或者创建并获取记录(如果不存在)。

问题在于,两个线程都在检查记录的存在并报告错误,然后都在插入新记录,从而在数据库中创建重复记录。

我试图将操作粘贴在事务中,但这只会产生数百个死锁。

有什么方法可以以线程安全的方式检查记录是否存在,以便第二个线程在第一个线程完成其插入之前不进行读取?我无法控制线程本身,只能控制它们正在执行的存储过程。

任何帮助,将不胜感激,

谢谢。

最佳答案

诀窍是在您的INSERT语句中添加一个WHERE,以便INSERT仅在该项目不存在时才起作用,然后是SELECT语句。假设可以通过您要编写的ID列来标识该记录:

INSERT INTO MyTable (ID,Col1,Col2,...)
SELECT @IDValue,@Col1Value,@Col2Value, ...
WHERE NOT EXISTS (SELECT ID
              FROM MyTable
              WHERE ID=@IDValue)

SELECT *
FROM MyTable
Where ID=@IDValue

您无需将语句放入事务中,因为每个语句都在其自己的隐式事务中执行。因此,不可能有两个INSERTS同时成功。

编辑:INSERT ... SELECT语法是必需的,因为TSQL在INSERT语句中不允许VALUES和WHERE部分。

10-01 00:42
查看更多