C# 检查/修改程序中的数据时使用读锁
在数据库中,假设当一辆汽车售出时,它将设置C# 检查/修改程序中的数据时使用读锁,c#,sql-server,locking,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(); } 现在有两个用户几乎同时进行购买操作 我想可能会出现以下情况: 就是说这辆车要卖两次,这是个问题
IsSold=true
,并记录买家
为了了解汽车是否已售出,我使用if来检查:
var car = GetCarFromDb().Where(car=>car.Id=2);
if(!car.IsSold){
car.IsSold = true; car.Buyer = thisUserName;
DbSaveChanges();
}
现在有两个用户几乎同时进行购买操作
我想可能会出现以下情况:
就是说这辆车要卖两次,这是个问题
将C#与MSSQL一起使用时是否可能发生这种情况 如果可能的话,我认为防止这种情况发生的唯一方法是在整个代码块期间给汽车数据读锁和写锁,如:
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
,即一辆汽车不会重复卖给两个用户
如果正确,那么如何练习GiveCarId2ReadLockWriteLock()代码>
或者,当两个用户几乎同时在不同的计算机/客户端上发送购买请求时,是否有其他方法阻止两个用户购买同一辆车
可能类似于MVC,或者使用存储库模式,或者在WebAPI中一次性处理一个请求,这样每个请求只能在前一个请求结束时输入
更新201710:
这里有一个讨论。尝试创建读锁(通过DB或应用程序)是可行的,但解决方案会很麻烦,可能会影响大多数事务的性能,而这些事务不在您担心的场景中
我建议让您的DB通过约束实现这一点,但要规范化您的DB模式
而不是有一个带列的Cars
表:
CarId
IsSold
买家
其他汽车用品
有两个表:
汽车
具有:
CarId
OtherCarStuff
汽车销售
有:
CarId
买家
销售日期
CarId
将是两个表的主键(考虑到我掌握的信息)
然后,当您尝试写入CarSales
表时&该车已经售出,您将违反primay key并知道它已售出。尝试通过DB或您的应用程序创建读锁将起作用,但是这个解决方案会很麻烦&可能会影响大多数事务的性能,而这超出了您所担心的场景
我建议让您的DB通过约束实现这一点,但要规范化您的DB模式
而不是有一个带列的Cars
表:
CarId
IsSold
买家
其他汽车用品
有两个表:
汽车
具有:
CarId
OtherCarStuff
汽车销售
有:
CarId
买家
销售日期
CarId
将是两个表的主键(考虑到我掌握的信息)
然后,当您尝试写入CarSales
表时&汽车已经售出,您将违反primay key并知道它已售出。您使用的是类似ORM的实体框架,还是直接数据库连接?实体框架正常。我突然想,如果使用EntityFramework,也许我可以使用控制器强制一次处理一个请求,直到请求结束,然后第二个请求可以进入,尽管我不知道实践细节是这个应用程序web还是桌面?两个用户使用客户端向服务器发送请求,客户端可以是浏览器或桌面程序,服务器接收请求,然后操作数据库。问题中的检查代码在clientOr客户端直接连接到数据库也是可以的,对于锁,如果客户端直接连接到数据库,那么锁代码可以写在客户端,如果是服务器操纵数据库,那么锁代码可以写在服务器上你使用类似ORM的实体框架吗,还是直接数据库连接?实体框架正常。我突然想,如果使用EntityFramework,也许我可以使用控制器强制一次处理一个请求,直到请求结束,然后第二个请求可以进入,尽管我不知道实践细节是这个应用程序web还是桌面?两个用户使用客户端向服务器发送请求,客户端可以是浏览器或桌面程序,服务器接收请求,然后操作数据库。问题中的检查代码在clientOr客户端直接连接到数据库也可以,对于锁,如果客户端直接连接到数据库,那么锁代码可以写在客户端,如果是服务器操作数据库,那么锁代码可以写在服务器谢谢你的回答,我认为这是可行的。酷。以这种方式规范化数据库将为您将来的维护和添加功能提供更大的灵活性。谢谢您的回答,我认为这是可行的。酷。以这种方式规范化数据库将为将来的维护和添加功能提供更大的灵活性。