在任何库存应用程序中是否需要处理线程方面的锁。就像我认为 ASP.NET 不是线程安全的一样。
假设有一种产品可用,其可用数量为 1,部分尝试预订该特定产品的用户数量为 40。那么哪个将获得该产品。或者发生什么。
即使这个问题是否可靠也不确定。
我对此不确定,请帮忙。
好吧,从技术上讲,您在这里甚至不是在谈论 ASP.NET,而是在谈论实体框架或您用来与 SQL Server 或您正在使用的任何其他持久数据存储进行通信的其他内容。关系数据库通常会进行行锁定,因此当一个客户端更新该行时,另一客户端无法读取该行,但您仍然可能会遇到并发问题。
您可以通过以下两种方式之一处理这种情况:悲观并发或乐观并发。通过悲观并发,您可以创建锁,并且同时尝试读取/写入相同数据的任何其他线程都会被拒绝。在多线程环境中,使用乐观并发更为常见,因为这为故障转移提供了一些发挥空间。
通过乐观并发,您可以对数据进行版本控制。作为一个简单的示例,假设我正在查找表中当前的小部件库存dbo.Widgets。我有一个列Version,最初可能被设置为“1”,并且在我的Stock列中有 100 个小部件。客户一想要购买一个小部件,因此我读取该行并记下版本 1。现在,我想要更新该列,因此我进行更新以设置为Stock99 和Version2,但我将其包含在我的 where 子句中Version = 1。但是,在最初读取该行和发送更新之间,另一个客户端购买了一个小部件并将该行的版本更新为 2。第一个客户端的更新失败,因为Version不再是 1。因此应用程序随后读取该行并尝试再次更新它,减去 1Stock并增加Version1。冲洗并重复。一般来说,在放弃并向用户返回错误之前,您会希望有一些向上的尝试限制,但在大多数情况下,您可能会发生一次碰撞,然后下一次碰撞会顺利进行。在这成为一个真正的问题之前,你的服务器必须受到急于购买小部件的人们的猛烈攻击。
当然,这是一种非常简单的方法,而且老实说,您实际上不需要自己管理。例如,只要您有 rowversion 列,实体框架就会自动为您处理并发:
[Timestamp]
public byte[] RowVersion { get; set; }
Run Code Online (Sandbox Code Playgroud)