Bloqueos y nivel de aislamiento en SQL Server 2005.

    Bajo mi punto de vista el punto debil de SQL Server siempre fueron los bloqueos. Conscientes de este problema, Microsoft se ha puesto manos a la obra y parece que en SQL Server 2005 han solucionado el problema.

    Para aquellos que no tengan ni idea de que es un bloqueo diremos que un bloqueo se produce cuando un usuario modifica o lee datos en una transacción.

    Por ejemplo, imaginemos que estamos actualizando una "factura" de estado "pendiente" a estado "pagado", durante el tiempo que dura la transacción (antes de hacer COMMIT o ROLLBACK), si otro usuario quiere ver el estado de la "factura" ... ¿que estado mostramos? ¡los datos están cambiando!. Si devolvemos "pendiente" no sería correcto, ya que el estado ha cambiado a "pagado", pero si devolvemos "pagado" tampoco es correcto, ya que la transacción podría hacer ROLLBACK y abriamos efectuado una lectura fantasma. SQL Server bloquea la fila (en el mejor de los casos) e impide el acceso a los datos afectados por la transacción, como consecuentcia el resto de usuarios concurrentes se quedan "bloqueados", sin posibilidad siquiera de leer los datos. Este es solo uno de los escenarios en los que el "bloqueo" hace acto de presencia, pero hay más. 


[Ampliar Imagen]

 
    Para controlar como afectan los bloqueos a las trasnsacciones, podemos modificar el nivel de aislamiento de las transacciones a través de la instrucción SET TRANSACTION ISOLATION LEVEL. Con esta instrucción controlamos como interpreta la transacción los bloqueos existentes y como genera nuevos bloqueos con sus operaciones de lectura/escritura.

    Su sintaxis general es la siguiente:


SET TRANSACTION ISOLATION LEVEL <opcion>

    Donde <opcion> puede tomar estos valores:

  • READ COMMITTED - La transacción no puede leer datos modificados por otras transacciones. Permite a otras transacciones pueden modificar los datos que se han leido. Esta opción es la predeterminada para SQL Server (incluido 2005).
  • READ UNCOMMITTED - La transacción es capaz de leer los datos modificados por otras transacciones pero que aún no han sido confirmadas (pendientes de COMMIT).
  • REPEATABLE READ - La transacción no puede leer datos modificados por otras transacciones y otras transacciones no pueden modificar los datos que se han leido.
  • SERIALIZABLE - Las instrucciones no pueden leer datos que hayan sido modificados, pero aún no confirmados, por otras transacciones y ninguna otra transacción puede modificar los datos leídos por la transacción actual ni insertar filas nuevas con valores de clave que pudieran estar incluidos en el intervalo de claves hasta que la transacción actual finalice.

    En este escenario, cualquiera de las opciones posibles tiene sus inconvenientes, por lo que la gestión de los bloqueos siempre ha sido un tema dificil de solventar en versiones anteriores de SQL Server. En SQL Server 2005 se ha incluido un nuevo nivel de aislamiento, el nivel SNAPSHOT que asegura la coherencia de los datos para toda la transacción:

  • SNAPSHOT - Activa el versionado de fila. Las instrucciones que se ejecuten en la transacción no verán las modificaciones de datos efectuadas por otras transacciones, en su lugar reciben una "copia coherente" de como estaban los datos al comienzo de la transacción. De este modo actuan otros gestores de bases de datos muy populares, como por ejemplo, ORACLE.

    El nivel de aislamiento SNAPSHOT no está disponible de forma predeterminada. Una base de datos con el nivel de aislamiento SNAPSHOT activado requiere de un mayor espacio de almacenamiento.

    Para activar la opción ALLOW_SNAPSHOT_ISOLATION con la siguiente instrucción:


 ALTER DATABASE MyDatabase
 SET ALLOW_SNAPSHOT_ISOLATION ON

    Con esta operación hemos activado el versionado de filas, pero como dijimos antes, por defecto las transacciones funcionan con el nivel de aislamiento READ COMMITTED, lo que obliga a las conexiones a especificar el nivel de aislamiento explicitamente a través de la sentencia SET TRANSACTION ISOLATION LEVEL SNAPSHOT si quieren acceder al versionado de filas. Para solucionar este problema, podemos cambiar el comportamiento de READ COMMITTED, para que se comporte como SNAPSHOT del siguiente modo:



 ALTER DATABASE MyDatabase
 SET READ_COMMITTED_SNAPSHOT ON

    Al establecer la opción READ_COMMITTED_SNAPSHOT, sólo se permite en la base de datos la conexión que ejecuta el comando ALTER DATABASE. No debe haber ninguna otra conexión abierta en la base de datos hasta que ALTER DATABASE haya finalizado. No es necesario que la base de datos esté en modo de usuario único. 
 

 

Pedro  Herrarte  Sánchez
Bloqueos y nivel de aislamiento en SQL Server 2005
Pedro Herrarte Sánchez

Pedro Herrarte, es consultor independiente, ofreciendo servicios de consultoría, análisis, desarrollo y formación. Posee mas de diez años de experiencia trabajando para las principales empresas de España. Es especialista en tecnologías .NET, entornos Web (ASP.NET, ASP.NET MVC,jQuery, HTML5), bases de datos (SQL Server y ORACLE) e integración de sistemas. Es experto en desarrollo (C#, VB.Net, T-SQL, PL/SQL, , ASP, CGI , C, Pro*C, Java, Essbase, Vignette, PowerBuilder y Visual Basic ...) y bases de datos (SQL Server y ORACLE). Pedro es MCP y MAP 2012, es fundador, diseñador y programador de www.devjoker.com..
Fecha de alta:17/04/2007
Última actualizacion:17/04/2007
Visitas totales:32123
Valorar el contenido:
Últimas consultas realizadas en los foros
Últimas preguntas sin contestar en los foros de devjoker.com