enero 27, 2006

Transacciones: todo un dolor de cabeza

Este artículo aplica a SQL Server 2000.

Si de verdad te interesa mejorar enormemente el rendimiento de tu aplicación, es importante que te enfoques en manejar eficientemente las transacciones. Las transacciones bloquean recursos de manera que pueden bloquear otras transacciones. Algunos trucos efectivos al momento de manejar transacciones los voy a listar a continuación, esperando que les sean lo más útil posible.

Evitar transacciones de larga duración. Dado que las transacciones efectúan bloqueos, lo más barato es mantener las transacciones lo más cortas posibles. Igual, se puede iniciar transacciones en la capa de aplicación. Una técnica bastante aceptada –y que me encanta utilizar- es realizar todas las validaciones previas, antes de iniciar la transacción. Quizá debas volverlas a verificar durante la transacción, pero la ventaja es que se puede evitar que por una de esas condiciones tengas que hacer un rollback en media transacción.

Nunca, jamás, utilizar transacciones que requieran de ingresos del usuario. Nada más que agregar.

Los datos más utilizados deberán ser accedidos al final de la transacción. Es mejor que todas las operaciones de lectura, sean colocadas al inicio de la transacción; las escrituras al final; y los recursos más accedidos al último. ¿Adivinaste? La idea es que los bloqueos son más cortos en los recursos más accedidos. Adiós a los bloqueos largos.

Acceder a los recursos en el mismo orden. Los deadlocks son las cosas mas molestas en la base de datos. Para evitarlos, debemos de tratar de utilizar los recursos en el mismo orden, en todo nuestro sistema. Si no lo hacemos corremos alto riesgo de enfrentarnos a escenarios de deadlock bastante frecuentes. Conseguir un sistema sin deadlocks es una tarea casi imposible; pero el objetivo deberá ser tratar de llevarlos al mínimo, reduciendo el tiempo en el que los bloqueos son efectuados. Esto incluso podríamos tratarlo en el futuro. Hay bastante que aprender acá.

Utilizar los hints de aislamiento (isolation). Si la lógica del negocio lo permite, podríamos llevar el nivel de aislamiento más bajo. Lo más común es utilizar el hint WITH NOLOCK en las sentencias select.

Las transacciones explícitas deberán de hacer commit o rollback. Se debe tratar que exista el manejo de errores adecuado, de manera que se hagan el commit o el rollback necesario. Sino jamás se cerrará la transacción. Si se tienen sospechas de alguna transacción abierta, se puede utilizar la sentencia DBCC OPENTRAN, que devolverá las transacciones abiertas.