2.1 Lectura no confirmada
El "nivel de aislamiento de transacciones" se refiere al grado de protección proporcionado por los mecanismos internos del DBMS (es decir, que no requiere programación especial) de todos o algunos de los tipos anteriores de inconsistencias de datos que ocurren durante la ejecución paralela de transacciones. El estándar SQL-92 define una escala de cuatro niveles de aislamiento:
- Leer sin confirmar
- Leer comprometido
- Lectura repetible
- Serializable
El primero de ellos es el más débil, el último es el más fuerte, cada subsiguiente incluye a todos los anteriores.
El nivel de aislamiento más bajo (primero). Si varias transacciones paralelas intentan modificar la misma fila de la tabla, la fila final tendrá un valor determinado por el conjunto completo de transacciones completadas con éxito. En este caso, es posible leer no solo datos lógicamente inconsistentes, sino también datos cuyos cambios aún no se han registrado.
Una forma típica de implementar este nivel de aislamiento es bloquear los datos mientras se ejecuta el comando de cambio, lo que garantiza que los comandos de modificación en las mismas filas que se ejecutan en paralelo se ejecuten secuencialmente y ninguno de los cambios se pierda. Las transacciones de solo lectura nunca se bloquean bajo este nivel de aislamiento.
2.2 Lectura comprometida
La mayoría de los DBMS industriales, en particular Microsoft SQL Server, PostgreSQL y Oracle, utilizan este nivel de forma predeterminada. En este nivel, se proporciona protección contra borrador, lectura "sucia", sin embargo, durante la operación de una transacción, otra puede completarse con éxito y se corrigen los cambios realizados por ella. Como resultado, la primera transacción funcionará con un conjunto de datos diferente.
La implementación de una lectura completa se puede basar en uno de dos enfoques: bloqueo o control de versiones.
Bloqueo de datos legibles y mutables.
Consiste en el hecho de que la transacción de escritura bloquea los datos mutables para las transacciones de lectura que operan en el nivel de lectura comprometida o superior hasta que se completa, evitando así la lectura "sucia", y los datos bloqueados por la transacción de lectura se liberan inmediatamente después de que se completa la operación. SELECT
(por lo tanto, una situación de "lectura no repetible" puede ocurrir en un nivel de aislamiento dado).
Guardar múltiples versiones de filas que cambian en paralelo.
Cada vez que se cambia una fila, el SGBD crea una nueva versión de esta fila, con lo cual la transacción que cambió los datos sigue funcionando, mientras que cualquier otra transacción de “lectura” devuelve la última versión comprometida. La ventaja de este enfoque es que es más rápido porque evita el bloqueo. Sin embargo, requiere, en comparación con el primero, un consumo de RAM significativamente mayor, que se gasta en almacenar versiones de fila.
Además, cuando varias transacciones modifican datos en paralelo, puede crear una situación en la que varias transacciones simultáneas realicen cambios incoherentes en los mismos datos (dado que no hay bloqueos, nada evitará que esto suceda). Luego, la transacción que se confirma primero guardará sus cambios en la base de datos principal, y las transacciones paralelas restantes serán imposibles de confirmar (ya que esto conducirá a la pérdida de la actualización de la primera transacción). Lo único que el DBMS puede hacer en tal situación es deshacer el resto de las transacciones y emitir un mensaje de error "El registro ya se modificó".
Los desarrolladores de DBMS eligen un método de implementación específico y, en algunos casos, se puede personalizar. Entonces, de manera predeterminada, MS SQL usa bloqueos, pero (en la versión 2005 y posteriores) al configurar el READ_COMMITTED_SNAPSHOT
parámetro de la base de datos, cambia a la estrategia de control de versiones, Oracle inicialmente funciona solo de acuerdo con el esquema de control de versiones. En Informix, puede evitar conflictos entre transacciones de lectura y escritura estableciendo una opción de configuración USELASTCOMMITTED
(a partir de la versión 11.1) que hace que la transacción de lectura reciba los últimos datos confirmados.
2.3 Lectura repetible
El nivel en el que una transacción de lectura "no ve" cambios en los datos que leyó anteriormente. Al mismo tiempo, ninguna otra transacción puede cambiar los datos leídos por la transacción actual hasta que finalice.
Los bloqueos en modo compartido se aplican a todos los datos leídos por cualquier instrucción en una transacción y se mantienen hasta que se completa la transacción. Esto evita que otras transacciones modifiquen las filas que leyó la transacción pendiente. Sin embargo, otras transacciones pueden insertar nuevas líneas que coincidan con las condiciones de búsqueda de las instrucciones contenidas en la transacción actual. Cuando la transacción actual reinicia la declaración, se obtendrán nuevas filas, lo que dará como resultado una lectura fantasma.
Dado que los bloqueos compartidos se mantienen hasta el final de la transacción, en lugar de liberarse al final de cada instrucción, el grado de simultaneidad es inferior al nivel de aislamiento READ COMMITTED
. Por lo tanto, generalmente no se recomienda utilizar este y niveles de transacción superiores innecesariamente.
2.4 Serializable
El más alto nivel de aislamiento; las transacciones están completamente aisladas entre sí, cada una se ejecuta como si no hubiera transacciones paralelas. Solo en este nivel las transacciones concurrentes no están sujetas al efecto de "lectura fantasma".
2.5 Soporte para aislamiento de transacciones en DBMS reales
Los DBMS transaccionales no siempre son compatibles con los cuatro niveles y también pueden introducir niveles adicionales. También hay varios matices al proporcionar aislamiento.
Entonces, en principio, Oracle no soporta el nivel cero, ya que su implementación de transacciones excluye las “lecturas sucias”, y formalmente no permite establecer el nivel de lectura Repetible, es decir, solo soporta (por defecto) Read committed
y Serializable
. Al mismo tiempo, a nivel de comandos individuales, en realidad garantiza la repetibilidad de lectura (si un comando SELECT
en la primera transacción selecciona un conjunto de filas de la base de datos, y en este momento una segunda transacción paralela cambia algunas de estas filas, entonces el conjunto de resultados recibido por la primera transacción contendrá filas sin cambios, como si no hubiera una segunda transacción). Oracle también admite las llamadas READ-ONLY
transacciones, que corresponden a Serializable
, pero no pueden cambiar los datos en sí.
Y Microsoft SQL Server admite los cuatro niveles estándar de aislamiento de transacciones y, además, el nivel SNAPSHOT, en el que la transacción ve el estado de los datos que se confirmaron antes de lanzarse, así como los cambios realizados por sí misma, es decir, se comporta como si hubiera recibido al inicio una instantánea de los datos de la base de datos y trabaja con ella. La diferencia con Serialized es que no se utilizan bloqueos, pero como resultado, es posible que no sea posible realizar cambios si una transacción simultánea ha cambiado los mismos datos anteriormente; en este caso, la segunda transacción, al intentar ejecutarse, COMMIT
generará un mensaje de error y será cancelada.
GO TO FULL VERSION