Etiquetas

, ,

reloj

SqlServer usa distintos tipos de aislamiento sobre las transacciones para aislarlas sobre las modificaciones de datos que en un momento dado se estén llevando a cabo, de este modo nos  protege de realizar lecturas sucias o lecturas fantasmas en entornos donde existen altos niveles de concurrencia .

Por defecto SqlServer utiliza un sistema de aislamiento basado en bloqueo READ COMMITTED lo cual hace que cualquiera que quiera leer la fila que esta siendo bloqueada deba esperar esto por supuesto esto pude provocar altos niveles de interbloqueo en bases de datos que reciban mucha concurrencia y no se encuentren bien diseñadas, pero a partir se SqlServer 2005 se añadió un nuevo nivel de aislamiento llamado READ COMMITTED SNAPSHOT el cual es una combinación entre los métodos READ COMMITTED y SNAPSHOT que en lugar de establecer un bloqueo que para las lecturas, utiliza un versionado de filas haciendo una copia de las filas que se están modificando y si alguien intenta leer no lo bloquea sino que devuelve el valor copiado, de tal modo, que las lecturas no son bloqueadas por las escrituras (y viceversa), su funcionamiento se basa en el almacenamiento de versiones de filas en TEMPDB por lo que este va a crecer de tamaño, sin embargo, pueden producirse lecturas no repetibles (non repeatable reads)

Si queremos cambiar el nivel de aislamiento de nuestra base de datos a  solo tenemos que ejecutar el siguiente comando.

USE <MiBaseDeDatos>

DECLARE @sql VARCHAR(8000)

SELECT @sql =
'ALTER DATABASE ' + DB_NAME() + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE ;
ALTER DATABASE ' + DB_NAME() + ' SET READ_COMMITTED_SNAPSHOT ON;
ALTER DATABASE ' + DB_NAME() + ' SET MULTI_USER; '
EXEC(@sql)

GO

Tambien es muy importante saber que el tiempo de espera por un bloqueo por defecto en SQL Server es infinito por lo que cualquier transacción permanecerá bloqueada infinitamente hasta que no termine el bloqueo, la solución a esto es utilizar la sentencia SET LOCK_TIMEOUT para especificar el tiempo máximo de espera por bloqueo (en milisegundos) también se puede saber el actual tiempo de espera por bloqueo, consultando el valor de la función del sistema @@LOCK_TIMEOUT.