Search code examples
javascriptnode.jscouchdbconflictcouchdb-nano

Handle 409 conflict document nodejs nano couchdb


I've been doing some research on this matter, that couchdb gives too many document conflicts.

I've seen a solution Updating a CouchDB document in nano saying this:

  1. Get document
  2. Save the _rev
  3. Apply changes
  4. Try to send updated document with saved _rev
  5. Go to step 1 in case of a 409

And I've tried to produce a function that does it, until the last step:

nano_update = function ( data, id, callback ) {

    var db = this;

    db.get( id, function( err, doc ) { //Get _rev of the document

        if ( !err ) {
            for ( var k in data ) {
                //Replace defined information while keeping the other
                if ( k.toLowerCase() !== '_rev' ) //Do not override _rev
                    doc[ k ] = data[ k ];
            }

        return db.insert( doc, id, callback ); //Insert with _rev to update
        }
    });
}

//Call it
var database = nano.use( 'databaseName' );
nano_update.call( database, { counter: Math.random() }, 'documentName' );

This is close to what I expect, however, if I open 2 windows making the same request continuously, it will reach a point where the 2 documents conflict making my server crash.

So, by saying '5. Go to step 1 incase of a 409', does it mean I have to do a recursion of calling the same function? If the documents continue to conflict, it's going to be an infinite loop for sure, and my server will just crash again. Currently, what I am doing is to NOT allow more than 1 request per 5 seconds, but that won't do well in the future.

How can I correctly handle 409 conflicting CouchDB documents using nano in nodejs?


Solution

  • The reason you get 409 is because the _rev is outdated, as every document update changes it. So don't hold on to the _rev.

    If you need to update multiple documents, try using the Bulk Document API, or you can use Partial Update, which kind of like a hack for you to update a document without specifying the _rev (it automatically read the _rev from the db).