2017-08-30 26 views
0

修改数据在数据库,假设当汽车被出售,它会设置IsSold = true,记录买家,使用读锁检查时/在程序

,并知道如果车已经卖了,我用的是如果检查:

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

现在有是两个用户做买入动作几乎在同一时间,

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

enter image description here

即车将被卖出两次,这是一个问题。


是它可能使用与MSSQL C#时,会发生什么?

如果可能的话,我想阻止它就像整个代码块中给汽车的数据读锁定和写锁定的唯一途径:

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

因此,如果用户1开始检查汽车销售, user2必须等到user1完成售车设置,那么user2将总是得到IsSold = true,即一辆车不会反复出售给2个用户。

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

或者有其他方法可以防止2个用户购买同一辆车,当2个用户差不多同时在不同的计算机/客户端上发送购买请求吗?

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

更新201710:

下面是一个Article in Entity Framework讨论。

+0

您使用的是ORM,如实体框架还是直接数据库连接? –

+0

实体框架没问题。我suddnely想如果使用Entiyframework,也许我可以使用控制器的力量来处理一个请求一次,直到请求结束然后第二个请求可以进来,虽然我不知道练习细节 –

+0

这个应用程序的网页或桌面? –

回答

2

尝试通过数据库或应用程序创建读取锁 - 可以工作,但解决方案会很麻烦&可能会影响大多数事务的性能,而这些事务会超出您所担心的情况。

我会建议让你的数据库通过约束来做到这一点,但是规范你的数据库模式。

代替具有1 Cars表列:

CarIdIsSoldBuyerOtherCarStuff

有2个表:

Cars具有:

CarIdOtherCarStuff

CarSales有:

CarIdBuyerSalesDate

CarId将是对两个表的主键(给出的信息,我有)

然后当你尝试写信给该车的CarSales表&已经售出,您将获得一个违反主要关键的&知道它已售出。

+0

感谢您的回答,我认为这是可行的。 –

+0

很酷。以这种方式规范你的数据库将为你今后的维护和增加功能提供更多的灵活性。 –