如何避免几乎同时添加SQL的重复行?

时间:2014-06-28 06:00:19

标签: sql-server-2008-r2 thread-safety unique-constraint razor-3

我的Razor 3网络应用正在为同一个外部密钥ID创建多个行,当多个输入进入相同的ID时,我希望有关如何避免这种情况的帮助。

SQL Server表存储有关另一个表中记录的数据(用户已经给出了关于某些事物的评级,其中还有一个用户表和一个速率事物表,因此评级表具有外键ID对于用户,评级事物的外键ID和评级值)。如果没有给出评级,则该用户ID和&事情id。

当用户评价某件事时,代码会调用服务器,该服务器会检查该用户之前是否对该事件进行了评级,如果是,则更新该行,但如果没有,则会创建一个新行:

// Get the member's rating for the thing, or create it.
Member_Thing_Rating memPref = (from mip in _myEntities.Member_Thing_Rating
                               where mip.thingID == thingId
                               where mip.MemberID == memberId
                               select mip).FirstOrDefault();
if (memPref == null)
{
   memPref = new Member_Thing_Rating();
   memPref.MemberID = memberId;
   memPref.thingID = thingId;

   _myEntities.Member_Thing_Rating.AddObject(memPref);
}

当用户非常快速地发送同一事物的两个评级时(这种情况经常发生),这可以很好地工作,这导致服务器创建两行,因为显然它是多线程的,并且两个线程都看不到现有的行,所以他们都创造了一个新的。

所以......我怎么能避免这个?

  • 我假设我可以某种方式(?)告诉SQL Server制定一个约束,memberIDthingID的组合在这个表中应该是唯一的,然后SQL Server的工作就是自动神奇地解决插入问题,并希望使用最新值。

  • 我想我可以某种方式(?)告诉这个例程锁定DB或成为单线程,以便在下一次调用同一例程之前完成添加一行。

我只是不知道要做的语法或UI / SQL步骤,尽管有点看。我认为我更喜欢线程锁解决方案,因为我比DB人更像程序员,所以我更喜欢我在代码中的复杂性。

感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

您可以轻松地向SQL Server表添加唯一约束,以确保永远不会在(memberID, thingID)列上显示重复项:

ALTER TABLE dbo.YourTableNameHere
ADD CONSTRAINT UQ_MemberID_ThingID UNIQUE(MemberID, ThingID)

现在,如果您的第二个连接尝试插入一个已包含在表中的(MemberID, ThingID)值的行,INSERT将失败,您将获得一个可以处理的异常例如获取这些ID中的一个或两个的新值。