我有一个问题,就是使用完全相同的参数在完全相同的时间调用相同的存储过程。
存储过程的目的是获取记录(如果存在),或者创建并获取记录(如果不存在)。
问题在于,两个线程都在检查记录的存在并报告错误,然后都在插入新记录,从而在数据库中创建重复记录。
我试图将操作粘贴在事务中,但这只会产生数百个死锁。
有什么方法可以以线程安全的方式检查记录是否存在,以便第二个线程在第一个线程完成其插入之前不进行读取?我无法控制线程本身,只能控制它们正在执行的存储过程。
任何帮助,将不胜感激,
谢谢。
最佳答案
诀窍是在您的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部分。