我试图了解在使用Node.js时使用模型实例时如何确保异步安全性.在这里,我在代码示例中使用了Mongoose ODM,但是这个问题适用于任何情况下,数据库都使用Node.js所采用的异步事件驱动I/O方法.
I am attempting to understand how to ensure aynchronous safety when using an instance of a model when using Node.js. Here, I use the Mongoose ODM in code samples, but the question applies to any case where a database is used with the asynchronous event-driven I/O approach that Node.js employs.
考虑以下代码(它将Mongoose用于MongoDB查询):
Consider the following code (which uses Mongoose for MongoDB queries):
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描述的文档.考虑以下代码:
In a separate part of the application, the document described by MyModel could be updated. Consider the following code:
MyModel.update( { _id : <id #1> }, { $set : { field1 : someValue }, callback );在代码段A中,MongoDB查询与已注册的回调一起发出,一旦文档准备就绪,将触发该查询. MyModel描述的文档的实例保留在内存中(在"doc"对象中).可能会发生以下顺序:
In Snippet A, a MongoDB query is issued with a registered callback to be fired once the document is ready. An instance of the document described by MyModel is retained in memory (in the "doc" object). The following sequence could occur:
问题
虽然Node以单线程方式运行代码,但在我看来,事件循环的任何运行都为潜在的过时数据打开了大门.如果遵守错误,请纠正我.
While Node runs code in a single-threaded manner, it seems to me that any allowance of the event loop to run opens the door for potentially stale data. Please correct me if this observance is wrong.
推荐答案不,不能保证在node.js/MongoDB中不会发生这种竞争情况.不过,它与node.js无关,而且对于支持并发访问的任何数据库(不仅仅是MongoDB),这都是可能的.
No, there are no guarantees that this type of race condition won't occur in node.js/MongoDB. It doesn't have anything to do with node.js though, and this is possible with any database that supports concurrent access, not just MongoDB.
但是,问题是使用MongoDB解决起来比较棘手,因为它不像典型的SQL数据库那样支持事务.因此,您必须使用MongoDB食谱这里.
The problem is, however, trickier to solve with MongoDB because it doesn't support transactions like your typical SQL database would. So you have to solve it in your application layer using a strategy like the one outlined in the MongoDB cookbook here.
更多推荐
在Node.js中防止与数据库相关的竞争条件
发布评论