我的设置:
我的问题:
保持库存完整性。想象一下,一个场景是两个用户提交了两个重叠项目集的发票。
一个天真(和错误)的实现将执行以下操作:
显然,这种实现很糟糕,因为两个用户的动作将相互交错并相互影响。在典型的阻塞服务器+关系数据库中,这通过复杂的锁定/事务方案来解决。
解决这个问题的点头+ mongoish方式是什么? node.js平台是否有为这类工具提供的工具?
答案 0 :(得分:5)
您可以查看使用MongoDB的两阶段提交方法,或者您可以完全忘记事务并通过服务总线方法解耦您的流程。以亚马逊为例 - 他们将允许您提交订单,但他们不会确认它,直到他们能够保护您的库存物品,收取您的卡等等。这不会发生在一次交易中 - 这是一个可以单独进行的一系列步骤,并且可以在必要时应用补偿步骤。
一个天真的总线实现将执行以下操作(请记住,这只是一个通用的建议供您使用,确切的实现将取决于您对并发的特定需求等):
听起来很复杂,但是一旦你有一个消息总线设置,它实际上相对简单。 A list of Node Message Bus Implementations can be found here.
有些开发人员甚至会完全跳过正式的消息总线并使用数据库作为他们的消息传递引擎,这可以在简单的实现中工作。 Google Mongo和Queues。
如果您不期望超过1台服务器且消息总线实现过于庞大,节点可以为您处理锁定和消息传递。例如,如果您确实想要使用节点锁定,则可以创建一个存储库存项目ID的数组。坦率地说,我认为消息总线是最好的方式。无论如何,这里是我过去使用的一些代码,用于处理与Node的简单外部资源锁定。
// 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;
});
};