Node.js + mongo + atomic update of multiple objects = headache

My setup:

  • Node.js
  • Mongojs
  • A simple database containing two collections - inventory and invoices.
  • Users can simultaneously create invoices.
  • An invoice can reference multiple inventory items.

My problem:

Maintain inventory integrity. Imagine that the scenario was for two users to send two invoices with overlapping sets of items.

A naive (and wrong) implementation will do the following:

  • For each item in the invoice, read the corresponding item from the inventory collection.
  • Correct the number of inventory items.
  • If any number of items falls below zero - refuse the request with the appropriate message to the user.
  • .
  • -.

, , . + /.

nodish + mongoish ? - , node.js ?

+5
1

MongoDB, . Amazon - , , , .. - , .

( , , concurrency ..):

  • . , , , .
  • " " , . . Mongo . TTL, (, 30 ). , , . , "lock".
  • , , X , , , , .
  • , , , , .. ..

, ​​ , . Node Bus Bus .

, . Google Mongo Queues.

, , Node . , node, , . , , , - . , , , 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;

            });
        };
+5

All Articles