Minimizar los interbloqueos

A pesar de que los interbloqueos no se pueden evitar totalmente, si se siguen ciertas convenciones de codificación se puede reducir su generación. La minimización de los interbloqueos puede aumentar el rendimiento de las transacciones y reducir la sobrecarga del sistema, debido a que:

  • Se revierten menos transacciones, al deshacer todo el trabajo que realiza la transacción.

  • Las aplicaciones vuelven a enviar menos transacciones debido a que se revirtieron cuando se produjo el interbloqueo.

Para ayudar a reducir los interbloqueos:

  • Obtenga acceso a los objetos en el mismo orden.

  • Evite la interacción con los usuarios en las transacciones.

  • Mantenga transacciones cortas y en un proceso por lotes.

  • Utilice un nivel de aislamiento inferior.

  • Utilice un nivel de aislamiento basado en las versiones de las filas.

    • Establezca la opción de base de datos READ_COMMITTED_SNAPSHOT en ON para que las transacciones de lectura confirmada utilicen las versiones de filas.

    • Utilice el aislamiento de instantánea.

  • Utilice conexiones enlazadas.

Obtener acceso a los objetos en el mismo orden

Si todas las transacciones simultáneas tienen acceso a los objetos en el mismo orden, es menos probable que se produzcan interbloqueos. Por ejemplo, si dos transacciones simultáneas obtienen un bloqueo en la tabla Supplier y, a continuación, en la tabla Part, una transacción se bloquea en la tabla Supplier hasta que finalice la otra transacción. Una vez confirmada o revertida la primera transacción, continúa la segunda, por lo que no se produce un interbloqueo. La utilización de procedimientos almacenados para todas las modificaciones de datos puede normalizar el orden de acceso a los objetos.

Diagrama en el que se muestra el modo de evitar un interbloqueo

Evitar la interacción con el usuario en las transacciones

Evite escribir transacciones que incluyan la intervención del usuario, ya que la velocidad de ejecución de los lotes que no requieren esta intervención es mucho mayor que la velocidad con la que el usuario debe responder manualmente a las consultas como, por ejemplo, contestar a la petición de un parámetro por parte de una aplicación. Por ejemplo, si una transacción espera una entrada del usuario y éste sale a comer o no vuelve hasta pasado el fin de semana, dicho usuario retrasa la finalización de la transacción. De esta forma, se degrada el rendimiento del sistema, ya que los bloqueos que mantiene la transacción sólo se liberan cuando se confirma o se revierte la transacción. Aunque no surja una situación de interbloqueo, las demás transacciones que obtienen acceso a los mismos recursos se bloquean mientras esperan a que la transacción finalice.

Mantener transacciones cortas y en un proceso por lotes

Normalmente, los interbloqueos se producen cuando varias transacciones de larga duración se ejecutan simultáneamente en la misma base de datos. Cuanto más dure la transacción, más tiempo se mantendrán los bloqueos exclusivos o de actualización, con lo cual se bloquean otras actividades y se originan posibles situaciones de interbloqueo.

Al mantener las transacciones en un proceso por lotes, se minimizan los viajes de ida y vuelta en la red durante una transacción y se reducen los posibles retrasos al completar la transacción y liberar los bloqueos.

Utilizar un nivel de aislamiento inferior

Determine si una transacción se puede ejecutar con un nivel de aislamiento inferior. Al implementar la lectura confirmada, se permite a una transacción leer los datos previamente leídos (no modificados) por otra transacción, sin tener que esperar a que la primera transacción finalice. Utilizar un nivel inferior de aislamiento, como la lectura confirmada, mantiene los bloqueos compartidos durante menos tiempo que un nivel superior de aislamiento, como el nivel serializable. De esta forma, se reduce la contención de bloqueos.

Utilizar un nivel de aislamiento basado en las versiones de las filas

Si la opción de base de datos READ_COMMITTED_SNAPSHOT se ha establecido en ON, la transacción que se ejecuta con el nivel de aislamiento de lectura confirmada utiliza la versión de filas en lugar de bloqueos compartidos durante las operaciones de lectura.

Nota

Algunas aplicaciones dependen del comportamiento de los bloqueos en el aislamiento de lectura confirmada. En estas aplicaciones, es preciso efectuar algunos cambios antes de habilitar esta opción.

El aislamiento de instantánea también utiliza las versiones de filas, que no emplean bloqueos compartidos en las operaciones de lectura. Antes de ejecutar una transacción con aislamiento de instantánea, debe establecerse en ON la opción de base de datos ALLOW_SNAPSHOT_ISOLATION.

Implemente estos niveles de aislamiento para reducir los interbloqueos que se pueden producir entre operaciones de lectura y escritura.

Utilizar conexiones enlazadas

Al utilizar conexiones enlazadas, dos o más conexiones abiertas por la misma aplicación pueden cooperar entre sí. Los bloqueos adquiridos por las conexiones secundarias se mantienen como si los adquiriera la conexión principal y viceversa. Por lo tanto, no se bloquean entre sí.