防止在 Asp.Net MVC 和 EF 中的多个并发请求期间出现争用情况



>我有一个控制器方法,它使用增量自定义订单 ID 在数据库中创建新订单(即ABC000005(

订单表包含以下字段

Id (PK)
Name
CustomOrderId
DateTime

为了实现这一点,我写了一个如下方法

var lastOrder = _dbContext.Order.OrderByDescending(x=>x.DateTime).First();
var lastOrderCustomId = lastOrder.CustomOrderId;
// Some other code which takes around 2 seconds
var newOrderId = //Calculation to increment custom order id (i.e. ABC000005 to ABC000006)
var newOrder = new Order();
newOrder.Name = "abc";
newOrder.DateTime = DateTime.UtcNow;
newOrder.CustomOrderId = newOrderId;
_dbContext.Order.Add(newOrder);
_dbContext.SaveChanges();

当对服务器有顺序请求时,上面的代码效果很好,但是当有并发请求时,2个请求将从数据库中获取相同的CustomOrderId,并在数据库中创建两个新的相同CustomOrderId值。

我为克服此问题而实施的解决方案之一是在代码上方使用线程lock,以便只有一个线程可以访问此代码,但在这种情况下,并发请求需要更多时间,并且创建顺序的整体功能会变慢。

这个特定问题还有其他解决方案吗?

锁定不是这样做的方法,因为这需要等到一个线程完成处理。解决此问题的一种方法是通过缓存。

  1. 当您收到创建新订单的请求时,请检查缓存中是否存在latest_custom_order_id
  2. 如果不存在,则获取上一个自定义订单 ID 并计算下一个订单 ID。
  3. 如果存在,则使用该订单 ID 计算客户订单 ID。
  4. 使用最新的订单 ID 更新缓存键的值。"latest_custom_order_id":"ABC0004"
  5. 保存订单

最新更新