node.js + mongo +多个实体的primefaces更新=头痛

我的设置:

  1. Node.js的
  2. Mongojs
  3. 包含两个集合的简单数据库 – 库存和发票。
  4. 用户可以同时创build发票。
  5. 发票可能涉及多个库存项目。

我的问题:

保持清单的完整性。 设想一个情景是两个用户提交两个重叠项目集的发票。

天真(错误的)实现将执行以下操作:

  1. 对于发票中的每个项目,从库存集合中读取相应的项目。
  2. 修复库存项目的数量。
  3. 如果任何物品数量低于零 – 放弃与相关消息的请求给用户。
  4. 保存库存项目。
  5. 保存发票。

显然,这个实现是不好的,因为这两个用户的行为将会交错并相互影响。 在典型的阻塞服务器+关系数据库中,这是通过复杂的locking/事务scheme解决的。

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

你可以看看MongoDB的两阶段提交方法,或者你可以完全忘记事务,并通过服务总线方法解耦你的进程。 以亚马逊为例 – 他们将允许您提交您的订单,但他们不会确认它,直到他们能够保证您的库存物品,收取您的卡等。这一切都不会发生在一个单一的交易 – 这是一个一系列可以单独出现的步骤,并且在必要时可以采取补偿步骤。

一个天真的总线实现将执行以下操作(请记住,这只是一个通用的build议,供您参考,具体实现取决于您对并发的特定需求等):

  1. 将订单放在队列中。 此时,您可以继续让您的客户等待,或者您可以感谢他们的订单,并让他们知道他们在处理完毕后会收到一封电子邮件。
  2. “库存员工”将获取订单并locking需要保留的库存项目。 这可以通过许多不同的方式来完成。 用Mongo你可以创build一个每个orderid都有一个文档的集合。 这个文件的ID应该是库存项目ID和一个合理的TTL(比如30秒)。 只要员工拥有locking,就可以pipe理所locking项目的库存水平。 一旦更改,它可以删除“locking”文件。
  3. 如果有另一个工作人员想要pipe理同一个物品而被locking,则可以将被阻止的工人置于睡眠模式中X秒,然后重试,或者更好的是,可以将请求放回到消息总线上以便拾取以后由另一个工作者。
  4. 一旦工作人员解决了所有的库存物品,它就可以在服务总线上放置另一条消息,表明应该收取一张卡片,或者处理应该收到一个通知来拉取库存,或者可以把电子邮件发送给制造人员订单等等

听起来很复杂,但是一旦你有一个消息总线设置,其实际上相对简单。 节点消息总线实现列表可以在这里find。

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

如果您不希望超过1个服务器,并且消息总线实现过于庞大,则节点可以为您处理locking和消息传递。 例如,如果您确实想要locking节点,则可以创build一个存储库存项目ID的数组。 尽pipe坦率地说,我认为巴士消息是最好的select。 无论如何,这里有一些我以前用来处理Node简单的外部资源locking的代码。

// 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; }); };