Prevención de condiciones de carrera relacionadas con la base de datos en Node.js

Visión general

Estoy tratando de entender cómo garantizar la seguridad sincrónica al usar una instancia de un modelo al usar Node.js. Aquí, uso el ODM Mongoose en ejemplos de código, pero la pregunta se aplica a cualquier caso en el que se use una base de datos con el enfoque de E / S controlado por eventos asíncronos que emplea Node.js.

Considere el siguiente código (que utiliza Mongoose para las consultas de MongoDB):

Fragmento A
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' ); }
    });
});

En una parte separada de la aplicación, el documento descrito por MyModel podría actualizarse. Considere el siguiente código:

Fragmento B
MyModel.update( { _id : <id #1> }, { $set : { field1 : someValue }, callback );

En el Fragmento A, se emite una consulta MongoDB con una devolución de llamada registrada que se activará una vez que el documento esté listo. Una instancia del documento descrito por MyModel se conserva en la memoria (en el objeto "doc"). La siguiente secuencia podría ocurrir:

Fragmento A ejecutaSe inicia una consulta para MyModel, registrando una devolución de llamada (callback A) para su uso posterior<< El bucle de eventos Nodo se ejecuta >>MyModel se recupera de la base de datos, ejecutando la devolución de llamada registrada (devolución de llamada A)Se inicia una consulta para MyOtherModel, registrando una devolución de llamada para su uso posterior (devolución de llamada B)<< El bucle de eventos Nodo se ejecuta >>Fragmento B ejecutaEl documento (id # 1) se actualiza<< El bucle de eventos Nodo se ejecuta >>MyOtherModel se recupera de la base de datos, ejecutando la devolución de llamada registrada (devolución de llamada B)La versión obsoleta del documento (id # 1) se usa incorrectamente en una comparación.Preguntas¿Hay alguna garantía de que este tipo de condición de carrera no ocurra en Node.js / MongoDB?¿Qué puedo hacer para evitar que este escenario ocurra de manera determinista?

Mientras que Node ejecuta el código de una manera de un solo hilo, me parece que cualquier asignación del bucle de eventos para ejecutarse abre la puerta a datos potencialmente obsoletos. Por favor, corrígeme si esta observancia es incorrecta.

Respuestas a la pregunta(1)

Su respuesta a la pregunta