Skip to content

MVCC en CouchDB. Ejemplo de uso desde Java.

by Cristian Requena on octubre 25th, 2010

En anteriores anotaciones se comentó el control de concurrencia de CouchDB, MVCC, que es una funcionalidad que le otorga la no dependencia de bloqueos u otros mecanismos similares.

Un control de concurrencia es un mecanismo de integridad que se basa en la necesidad de disponer de la última modificación de un dato para poderlo volver a modificar, esto es, se requiere obtener el archivo/documento/etc. más reciente para poderlo actualizar. A pequeña escala es algo trivial (-Pepe, pásame el documento de la versión, que añado un párrafo; -Paco, pásame el documento que borro una imagen; etc.), pero cuando se trata con un gran conjunto de datos se torna imposible saber quién dispone del documento más reciente/más actualizado sin la ayuda externa de una utilidad tal como CVS, Subversion, etc.
Las empresas y organizaciones de desarrollo de software, así como los grupos de desarrolladores, utilizan estos mecanismos para modificar el código producido, pero cuando se trata del área de gestión de bases de datos, y siempre que se trate de bases de datos relacionales, no queda otra opción que el uso de bloqueos (normalmente automáticos de los mismos RDBMS), sin tener la posibilidad de saber si el documento fue previamente modificado desde su obtención.

El objetivo de CouchDB en esta área es el de proveer de un MVCC fiable que veremos en acción en el siguiente ejemplo, cuando se intente modificar dos veces un mismo documento partiendo de una misma versión.

Session s = new Session("lamec",5984); // Crear una sesión/conexión contra CouchDB.
Database db = s.getDatabase("demo"); // Acceder a una base de datos del servidor.
Document doc1 = db.getDocument("es.nosql.demo.clientes.12345678Z");	// Obtener un documento
Document doc2 = db.getDocument("es.nosql.demo.clientes.12345678Z");	// Obtener el mismo documento en la misma revisión
doc1.put("Apellidos", "González1 Zapatero1");
doc2.put("Apellidos", "González2 Zapatero2");
db.saveDocument(doc1); // Persistir el documento.
db.saveDocument(doc2); // Persistir el documento por segunda vez, partiendo de la misma revisión.

Resultado:

ADVERTENCIA: Error adding document - conflict Document update conflict.
RESP: [null] /demo/es.nosql.demo.clientes.12345678Z [409]  => {"error":"conflict","reason":"Document update conflict."}

En resumen, se permite la primera modificación del documento pero posteriormente, cuando se intenta modificarlo partiendo de una revisión antigua, se crea un conflicto y no se permite el cambio.

Una forma rápida de lidiar con estos Warnings es el de, simplemente, dejar hacer a CouchDB. Esto se consigue modificando la revisión del documento a la última disponible justo antes de lanzar su grabación:

Session s = new Session("lamec",5984); // Crear una sesión/conexión contra CouchDB.
Database db = s.getDatabase("demo"); // Acceder a una base de datos del servidor.
Document doc1 = db.getDocument("es.nosql.demo.clientes.12345678Z");	// Obtener un documento
Document doc2 = db.getDocument("es.nosql.demo.clientes.12345678Z");	// Obtener un documento
doc1.put("apellidos", "González1 Zapatero1");
doc2.put("apellidos", "González2 Zapatero2");
db.saveDocument(doc1);	// Persistir el documento.
doc2.setRev(db.getDocument(doc2.getId()).getRev());	// Modificar la revisión.
db.saveDocument(doc2);	// Persistir el documento partiendo de la última modificación.

Et voilà: se actualiza el documento con los últimos cambios, descartando la modificación de doc1:

Otra forma de gestionarlo es detectar cuando se produce un error de actualización y revisar manualmente los cambios entre una revisión y otra, para producir un documento que una ambas revisiones. Esto es más laborioso, pero puede ser interesante según el tipo de entidades con las que se trabaje.

One Comment
  1. Estoy no Seguro el lugar estás Información, pero buen gran tema.

    I debe pasar un tiempo averiguar más o elaboración más.
    Gracias para magnífico Información Yo solía ser en busca de este info para mi misión.

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS