En la programación de gestión de datos, el control de concurrencia es un mecanismo diseñado para garantizar que las operaciones concurrentes generen resultados precisos. Estos resultados también deben obtenerse de manera oportuna. El control de simultaneidad se ve muy a menudo en bases de datos donde hay un caché de información de búsqueda para que los usuarios la obtengan.
Los programadores intentan diseñar una base de datos de tal manera que el efecto de las transacciones importantes en los datos compartidos sea equivalente en serie. Lo que esto significa es que los datos que entran en contacto con conjuntos de transacciones estarían en un cierto estado en el que los resultados se pueden obtener si todas las transacciones se ejecutan en serie y en un orden particular. A veces, esos datos no son válidos como resultado de dos transacciones al mismo tiempo que los modifican.
Hay varias formas de garantizar que las transacciones se ejecuten una tras otra, incluido el uso de la exclusión mutua y la creación de un recurso que decida qué transacciones tienen acceso. Sin embargo, esto es excesivo y no permitirá que un programador se beneficie del control de concurrencia en un sistema distribuido. El control de simultaneidad permite la ejecución simultánea de múltiples transacciones mientras mantiene estas transacciones alejadas entre sí, lo que garantiza la linealización. Una forma de implementar el control de concurrencia es el uso de un bloqueo exclusivo en un recurso particular para ejecuciones de transacciones en serie que comparten recursos. Las transacciones bloquearán un objeto destinado a ser utilizado, y si alguna otra transacción realiza una solicitud para el objeto que está bloqueado, esa transacción tiene que esperar a que el objeto se desbloquee.
La implementación de este método en sistemas distribuidos involucra administradores de bloqueo, servidores que emiten bloqueos de recursos. Esto es muy similar a los servidores para exclusiones mutuas centralizadas, donde los clientes pueden solicitar bloqueos y enviar mensajes para la liberación de bloqueos en un recurso en particular. Sin embargo, la conservación de la ejecución en serie sigue siendo necesaria para el control de la concurrencia. Si dos transacciones separadas acceden a un conjunto de objetos similar, los resultados deben ser similares y como si estas transacciones se hubieran ejecutado en un orden particular. Para garantizar el orden en el acceso a un recurso, se introduce el bloqueo de dos fases, lo que significa que no se permiten nuevos bloqueos en las transacciones tras la liberación de un bloqueo separado.
En el bloqueo de dos fases para el control de la concurrencia, su fase inicial se considera la fase de crecimiento, donde la transacción adquiere el bloqueo necesario. La siguiente fase se considera una fase de contracción, en la que se liberan los bloqueos de la transacción. Hay problemas con este tipo de bloqueo. Si las transacciones se anulan, otras transacciones pueden utilizar datos de objetos modificados y desbloqueados por transacciones anuladas. Esto daría lugar a la anulación de otras transacciones.