gpt4 book ai didi

node.js + mongodb + 多个实体的原子更新 = 头疼

转载 作者:IT老高 更新时间:2023-10-28 12:29:12 27 4
gpt4 key购买 nike

我的设置:

  1. Node.js
  2. 蒙古人
  3. 一个包含两个集合的简单数据库 - 库存和发票。
  4. 用户可以同时创建发票。
  5. 一张发票可能涉及多个库存项目。

我的问题:

保持库存完整性。想象一个场景,两个用户提交两张带有重叠项目集的发票。

一个天真的(和错误的)实现会做以下事情:

  1. 对于发票中的每个项目,请从库存集合中读取相应项目。
  2. 固定库存元素的数量。
  3. 如果任何商品数量低于零 - 放弃请求并向用户发送相关消息。
  4. 保存库存项目。
  5. 保存发票。

显然,这种实现很糟糕,因为两个用户的操作会交错并相互影响。在典型的阻塞服务器 + 关系数据库中,这是通过复杂的锁定/事务方案解决的。

解决这个问题的 nodish + mongoish 方法是什么? node.js 平台有没有为这类事情提供的工具?

最佳答案

您可以查看 MongoDB 的两阶段提交方法,或者您可以完全忘记事务并通过服务总线方法解耦您的流程。以亚马逊为例 - 他们将允许您提交订单,但在他们能够保护您的库存元素、从您的卡中扣款等之前,他们不会确认。这一切都不会发生在单笔交易中 - 这是一个可以单独发生的一系列步骤,并且可以在必要时应用补偿步骤。

一个简单的总线实现会执行以下操作(请记住,这只是一个通用的建议,供您使用,具体的实现取决于您对并发的具体需求等):

  1. 将订单放入队列中。此时,您可以继续让您的客户等待,或者您可以感谢他们的订购并让他们知道他们将收到一封电子邮件已处理。
  2. “库存工作人员”将抓取订单并锁定库存它需要保留的项目。这可以在许多不同的情况下完成方法。使用 Mongo,您可以创建一个集合,其中每个 orderid 都有一个文档。该文档的 ID 为库存项目 ID 和一个合理的 TTL(比如 30 秒)。只要 worker 有锁,就可以管理其锁定的项目的库存水平。一旦它进行了更改,它可以删除“锁定”文档。
  3. 如果有另一个 worker 来管理同一个项目当它被锁定时,你可以让被阻塞的工作人员进入休眠模式X 秒,然后重试,或者更好的是,您可以将请求返回到消息总线,稍后由另一个接收 worker 。
  4. 一旦工作人员解决了所有库存项目,它就可以在指示卡的服务总线上放置另一条消息应收费,或处理应收到通知拉库存,或者可以向制作人发送电子邮件订单等等等等。

听起来很复杂,但是一旦设置了消息总线,它实际上就相对简单了。 A list of Node Message Bus Implementations can be found here.

一些开发人员甚至会完全跳过正式的消息总线,并使用数据库作为他们的消息传递引擎,该引擎可以在简单的实现中工作。 Google Mongo 和队列。

如果您不希望超过 1 个服务器并且消息总线实现过于庞大, Node 可以为您处理锁定和消息传递。例如,如果您真的想用 Node 锁定,您可以创建一个存储库存项目 ID 的数组。虽然,坦率地说,我认为消息总线是最好的方式。不管怎样,这里有一些我过去用来处理简单的外部资源锁定的代码。

// attempt to take out a lock, if the lock exists, then place the callback into the array.
this.getLock = function( id, cb ) {

if(locks[id] ) {
locks[id].push( cb );
return false;
}
else {
locks[id] = [];
return true;
}
};

// call freelock when done
this.freeLock = function( that, id ) {
async.forEach(locks[id], function(item, callback) {
item.apply( that,[id]);
callback();
}, function(err){
if(err) {
// do something on error
}

locks[id] = null;

});
};

关于node.js + mongodb + 多个实体的原子更新 = 头疼,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12273596/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com