在程序中检查/修改数据时使用读锁定

时间:2017-08-30 09:18:07

标签: c# sql-server locking

在数据库中,假设汽车售出时,它会设置IsSold = true并记录买家,

并且要知道汽车是否已售出,我使用if检查:

var car = GetCarFromDb().Where(car=>car.Id=2);
if(!car.IsSold){
   car.IsSold = true;  car.Buyer = thisUserName;  
   DbSaveChanges();
}

现在有两个用户几乎同时进行购买行动,

我想象下面的情况可能会发生:

enter image description here

那是汽车将被出售两次,这是一个问题。


将C#与MSSQL一起使用时可能会发生吗?

如果可能的话,我认为防止它的唯一方法是在整个代码块中给出汽车数据Read Lock和Write Lock,如:

GiveCarId2ReadLockWriteLock();
var car = GetCarFromDb().Where(car=>car.Id=2);
if(!car.IsSold){
   car.IsSold = true;  car.Buyer = thisUserName;  
   DbSaveChanges();
}
ReleaseCarId2ReadLockWriteLock();

因此,如果User1开始检查汽车是否已售出,则user2必须等到user1完成设置售出的汽车,因此user2将始终获得IsSold = true,即一辆汽车不会反复出售给2个用户。 / p>

如果是对的,那么如何练习GiveCarId2ReadLockWriteLock();

还是有其他方法可以防止2个用户购买同一辆车,当2个用户几乎同时发送购买请求并且在不同的计算机/客户端上?

也许像MVC,或使用存储库模式,或者做一些特殊技能在WebAPI中处理一次请求,以便每个请求在前一个请求结束时可以输入?

更新201710:

这是一个Article in Entity Framework讨论它。

1 个答案:

答案 0 :(得分:2)

尝试通过数据库或您的应用程序创建读锁 - 会起作用,但解决方案会很麻烦。可能会影响大多数交易的表现,这些交易将超出您所担心的情况。

我建议让你的数据库通过约束来做到这一点,但要规范化你的数据库架构。

而不是包含1个 Cars 表:

CarId IsSold Buyer OtherCarStuff

有两张桌子:

Cars 有:

CarId OtherCarStuff

CarSales 有:

CarId Buyer SalesDate

CarId将成为两个表的主键(给定我的信息)

然后当您尝试写入CarSales表&该车已售出,您将违反首要钥匙&知道它已售出。