Breve introducción de Read Uncommitted a Snapshot Isolation

Otras de las dudas muy habituales para los iniciados (y no tan iniciados) en SQL Server (y también en cualquier desarrollador de cualquier motor de base de datos) es que tipo de niveles de bloqueos existen (isolation level), para que sirven, en que caso usarlos y que desventajas tiene su uso.
Por lo tanto, decidí hacer un muy breve resumen de los distintos niveles existentes. Si bien, este post especifico esta enfocado en SQL Server, conceptualmente, puede servir para cualquier motor. Los niveles de aislamiento están especificados en el estandar ANSI.

Read Uncommitted: A veces llamado “lectura sucia” o “diry read”. Una transacción ejecutada en este nivel de aislamiento, puede leer datos que están siendo modificados por otra transacción concurrente. Ejemplo: Transacción T2 hace un update sobre el registro R1, sin embargo, la transacción T1 puede leer el registro R1 modificado, a pesar de que T2 potencialmente puede hacer un roll back sobre el mismo.

  • Ventajas: No se necesita hacer un lockeo para leer datos, aunque si para poder modificarlos.
  • Contras: No se puede garantizar la consistencia de los datos leídos. Puede darse el caso de que sea lea un dato que luego no exista más.
  • Uso habitual: En situaciones de alta concurrencia donde la potencial inconsistencia de datos sea tolerada.

Read Committed: Una transacción ejecutada en este nivel de aislamiento puede leer solamente datos commiteados. Por ejemplo, si una transacción concurrente T2 hace un update sobre el registro R1, la transacción T1 no podrá acceder al mismo y va a quedar bloqueada hasta que T2 haga un commit o un rollback sobre el registro.

  • Ventajas: Buen balance entre concurrencia y consistencia.
  • Contras: Mayor nivel de bloqueo.
  • Uso habitual: Es el isolation level mas común, de hecho, el que se usa por defecto en SQL Server.

Repeatable Read: Una transacción ejecutada en este nivel de aislamiento solo puede leer información comiteada con la garantía de que mientras dure la transacción, nadie va a poder leer esos datos. Esto significa que si vuelvo a leer esos datos dentro de la transacción, tengo total seguridad de que el resultado va a ser exactamente el mismo, ya que están bloqueados para la escritura en otra transacción.
Ejemplo: Asumamos que tenemos la tabla Cuentas que guarda el balance monetario de los clientes. Empezamos la transacción T1 con filtrando todos los balances cuyo monto sea mayor a 1000. Supongamos que nos devuelve 10 registros. Ahora empieza otra transacción T2, que inserta un nuevo registro cuyo balance es de 1020 y comitea. Si consultamos nuevamente en la transacción T1 todos los balances mayores a 1000, ahora nos va a devolver 11 registros. Esto se debe a que la transacción T1 bloqueó el conjunto de registros seleccionados en la consulta, pero no el predicado del filtro.
Ahora, si dentro de la transacción T2 intento eliminar todos los registros cuyo balance sea mayor a 1000, va a ocurrir un bloqueo, ya que están lockeados por la transacción T1.

  • Ventajas: Alta consistencia en los datos.
  • Contras: Mayor nivel de bloqueos y disminución del grado de concurrencia.
  • Uso habitual: En operaciones bancarias o financieras que requieran un grado de exactitud muy alto.

Serializable: Una transacción T1 ejecutada en este nivel ofrece el mayor grado de consistencia posible, eliminado los registros fantasmas. El motor puede llegar a bloquear incluso la tabla entera, para garantizar la máxima consistencia de datos.

  • Ventajas: Consistencia de datos absoluta.
  • Contras: Altísimo grado de bloqueo y muy bajo nivel de concurrencia, ya que las tablas pueden ser bloqueadas en su totalidad mientras se realiza una transacción.
  • Uso habitual: No es muy habitual. Casos muy raros cuando se requiera una gran consistencia de datos.

Adicionalmente, existen nuevos niveles de aislamiento a partir de SQL Server 2005.

Read-Committed-Snapshot : Este no es un nuevo nivel de aislamiento, sino una reimplementación del read comitted pero sin bloqueos.
SQL Server implementa versionado de registros mediante copias (snapshots) para evita el bloqueo.

  • Ventajas: Acceso no bloqueante a datos consistentes.
  • Contras: Mayor overhead para mantener el versionado de datos.
  • Uso habitual: Minimar los bloqueos lectura/escritura y el uso de el hint NOLOCK.

Snapshot Isolation: Ya habíamos hablado acá sobre este nivel de lockeo. Una transacción bajo este nivel de aislamiento, trabaja sobre una copia (o “snapshot”) de la base de datos. Cuando finaliza la transacción, hace un merge entre la copia y la base de datos.

  • Ventajas: Mayor nivel de consistencia incluso que un “repetable red”, con mayor nivel de concurrencia, ya que no realiza lockeos.
  • Contras: Mayor overhead para mantener las distintas versiones de un conjunto de datos, lo que impacta en la performance.
  • Uso Habitual: Cuando se necesita obtener información muy consistente y en entornos de alta concurrencia.

Recordemos que para activar especificar el nivel de aislamiento, se debe ejecutar SET TRANSACTION ISOLATION LEVEL <ISOLATION>

Advertisement

Publicado el febrero 24, 2011 en MVCC, SQL Server. Añade a favoritos el enlace permanente. 1 comentario.

Deja un comentario

Fill in your details below or click an icon to log in:

Logo de WordPress.com

You are commenting using your WordPress.com account. Log Out / Cambiar )

Twitter picture

You are commenting using your Twitter account. Log Out / Cambiar )

Facebook photo

You are commenting using your Facebook account. Log Out / Cambiar )

Connecting to %s

Seguir

Get every new post delivered to your Inbox.