Control de concurrencia optimista
# Control de concurrencia optimista

El control de concurrencia optimista (en inglés Optimistic concurrency control o OCC) es un método de control de concurrencia que se aplica a sistemas transaccionales, tales como sistemas de gestión de bases de datos relacionales y memoria transaccional de software. El OCC asume que múltiples transacciones se pueden completar frecuentemente sin interferir entre sí. Mientras se ejecutan, las transacciones utilizan recursos de datos sin adquirir bloqueos en esos recursos. Antes de hacer el commit, cada transacción verifica que ninguna otra transacción ha modificado los datos que ha leído. Si la comprobación revela modificaciones en conflicto, la transacción que iba a hacer commit hace un rollback y se puede reiniciar. El control de concurrencia optimista fue propuesto por primera vez por H. T. Kung.

El OCC se utiliza generalmente en entornos con baja contención de datos. Cuando los conflictos son poco frecuentes, las transacciones se pueden completar sin el coste de la gestión de bloqueos y sin tener transacciones esperando a que se borren los bloqueos de otras transacciones, dando lugar a un mayor rendimiento que otros métodos de control de concurrencia. Sin embargo, si la contención de recursos de datos es frecuente, el coste de reiniciar las transacciones repetidamente perjudica el rendimiento de manera significativa; comúnmente se piensa que otros métodos de control de concurrencia tienen un mejor rendimiento en estas condiciones. Sin embargo, los métodos basados en bloqueos ("pesimistas") también pueden ofrecer un rendimiento pobre porque los bloqueos pueden limitar drásticamente la concurrencia efectiva incluso cuando se evitan los deadlocks.

## Fases del OCC

Más en concreto, las transacciones del OCC implican estas fases:

* Inicio: Grabar un timestamp que marca el inicio de la transacción.
* Modificar: Leer los valores de la base de datos y tentativamente escribir cambios.
* Validar: Comprobar si otras transacciones han modificado datos que esta transacción ha utilizado (leído o escrito). Esto incluye las transacciones que se han completado con posterioridad al tiempo de inicio de esta transacción y, opcionalmente, las transacciones que aún están activas en el momento de la validación.
* Commit/Rollback: Si no hay conflicto, hacer que todos los cambios surtan efecto. Si hay un conflicto, resolverlo, típicamente abortando la transacción, aunque otros sistemas de resolución son posibles. Se debe tener cuidado para evitar un bug TOCTTOU, especialmente si esta fase y la anterior no se realizan como una única operación atómica.

## Uso en la Web

La naturaleza sin estado de HTTP hace que el bloqueo no sea factible para interfaces de usuarios web. Es común que un usuario empiece a editar un registro y, a continuación, salga sin seguir un enlace de "cancelar" o " cerrar sesión". Si se utilizan bloqueos, otros usuarios que intentan editar el mismo registro deben esperar hasta que el bloqueo del primer usuario termine.

HTTP proporciona una forma de OCC incorporada: El método GET devuelve un ETag para un recurso y PUTs posteriores utilizan el valor del ETag en las cabeceras If-Match ; mientras que el primer PUT tendrá éxito, el segundo no, ya que el valor de If-Match está basado en la primera versión del recurso.

Algunos sistemas de gestión de bases de datos ofrecen OCC de forma nativa - sin necesidad de código de aplicación especial. Para otros, la aplicación puede implementar una capa de OCC fuera de la base de datos, y no tener que esperar o sobrescribir registros en silencio. En tales casos, el formulario incluye un campo oculto con el contenido del registro original, un timestamp, un número de secuencia, o un token opaco. Al enviar (submit), se compara con la base de datos. Si es diferente, se invoca el algoritmo de resolución de conflictos.

### Ejemplos

* Las páginas de edición de MediaWiki utilizan OCC.
* Bugzilla usa OCC; los conflictos de edición son llamados "mid-air collisions".
* El framework Ruby on Rails tiene una API para OCC.
* El framework Grails utiliza OCC en sus convenciones predeterminadas.
* El motor de bases de datos GT.M utiliza OCC para la gestión de transacciones (incluso las actualizaciones individuales son tratadas como mini-transacciones).
* Entity Framework de Microsoft (incluyendo Code-First) tiene soporte incorporado para OCC basado en un valor de timestamp binario.
* Mimer SQL es un DBMS que sólo implementa el control de concurrencia optimista.
* El almacén de datos de Google App Engine utiliza OCC.
* El motor de búsqueda ElasticSearch soporta OCC a través del atributo de versión.
* El esquema de gestión de transacciones del sistema de gestión de base de datos orientado a columnas MonetDB se basa en OCC.
* La mayoría de las implementaciones de memoria transaccional de software utilizan el bloqueo optimista.
