首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Node.js中防止与数据库相关的竞争条件

问在Node.js中防止与数据库相关的竞争条件
EN

Stack Overflow用户
提问于 2012-11-02 07:12:03
回答 1查看 12.3K关注 0票数 29

概述

我试图了解如何确保在使用Node.js时使用模型实例时的时间安全性。在这里,我在代码示例中使用Mongoose,但是这个问题适用于Node.js使用的异步事件驱动I/O方法使用数据库的任何情况。

请考虑以下代码(它将Mongoose用于MongoDB查询):

片段A

代码语言:javascript
复制
MyModel.findOne( { _id : <id #1> }, function( err, doc ) {
    MyOtherModel.findOne( { _id : someOtherId }, ( function(err, otherDoc ) {
        if (doc.field1 === otherDoc.otherField) {
            doc.field2 = 0; // assign some new value to a field on the model
        }
        doc.save( function() { console.log( 'success' ); }
    });
});

在应用程序的单独部分中,可以更新MyModel描述的文档。考虑以下代码:

片段B

代码语言:javascript
复制
MyModel.update( { _id : <id #1> }, { $set : { field1 : someValue }, callback );

在Snippet中,向MongoDB查询发出一个已注册的回调,一旦文档准备就绪,将触发该回调。MyModel描述的文档的一个实例保留在内存中(在"doc“对象中)。可能出现以下顺序:

  1. 片段--执行
  2. 为MyModel启动一个查询,注册一个回调(回调A)以供以后使用
  3. <<节点事件循环运行>>
  4. 从数据库中检索MyModel,执行已注册的回调(回调A)
  5. 为MyOtherModel启动一个查询,注册一个回调供以后使用(回调B)
  6. <<节点事件循环运行>>
  7. 执行代码段B
  8. 更新文档(id #1)
  9. <<节点事件循环运行>>
  10. 从数据库中检索MyOtherModel,执行注册的回调(回调B)
  11. 文档的陈旧版本(id #1)在比较中被错误地使用。

问题

  1. 是否可以保证Node.js/MongoDB不会出现这种类型的争用状态?
  2. 我能做些什么来决定性地防止这种情况的发生?

虽然Node以单线程的方式运行代码,但在我看来,任何允许运行的事件循环都会为可能过时的数据打开大门。如果这种做法是错误的,请纠正我。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-02 12:25:00

不,不能保证node.js/MongoDB中不会出现这种类型的争用条件。不过,它与node.js没有任何关系,而且这与任何支持并发访问的数据库都是可能的,而不仅仅是MongoDB。

但是,使用MongoDB解决问题更棘手,因为它不像典型的SQL数据库那样支持事务。因此,您必须在应用程序层中使用类似于MongoDB食谱here中概述的策略来解决这个问题。

票数 21
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13190885

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档