>我有一个控制器方法,它使用增量自定义订单 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
,以便只有一个线程可以访问此代码,但在这种情况下,并发请求需要更多时间,并且创建顺序的整体功能会变慢。
这个特定问题还有其他解决方案吗?
锁定不是这样做的方法,因为这需要等到一个线程完成处理。解决此问题的一种方法是通过缓存。
- 当您收到创建新订单的请求时,请检查缓存中是否存在
latest_custom_order_id
。 - 如果不存在,则获取上一个自定义订单 ID 并计算下一个订单 ID。
- 如果存在,则使用该订单 ID 计算客户订单 ID。
- 使用最新的订单 ID 更新缓存键的值。
"latest_custom_order_id":"ABC0004"
- 保存订单