¿Cuál es la relación exacta entre una transacción de base de datos y el bloqueo?

16

Esta es una pregunta humilde hecha con el espíritu de aumentar mi conocimiento; amablemente sea amable en su respuesta.

Como desarrollador de aplicaciones desde hace mucho tiempo, sé en algún nivel qué es una transacción (las uso todo el tiempo). Dejando de lado los niveles de aislamiento de transacciones por el momento, en un nivel alto, una transacción permite que un bloque de trabajo se complete por completo o no se complete, y permite una cierta cantidad de aislamiento de otras actividades de modificación de la base de datos.

También sé qué es (en varias bases de datos) un bloqueo, o al menos cómo se comporta uno (si bloqueo una tabla de manera explícita, entonces ningún otro proceso o subproceso puede actualizar nada sobre esa tabla).

Lo que claramente no tengo claro es: en varias bases de datos, cuando bloqueo explícitamente una fila o una tabla, ¿estoy empleando exactamente las mismas construcciones que usan las instalaciones de transacción de la base de datos debajo de las cubiertas para hacer que la transacción funcione correctamente?

Es decir, se me ocurre que para que una transacción sea atómica y aislada, debe estar bloqueándose. ¿Es este bloqueo iniciado por la transacción, oculto por la transacción, el mismo tipo de bloqueo que varias bases de datos me permiten acceder a través de construcciones como comandos SELECT FOR UPDATEexplícitos LOCK? ¿O son estos dos conceptos completamente diferentes?

Nuevamente, me disculpo por la ingenuidad de esta pregunta; Estoy feliz de ser señalado a fuentes más fundamentales.

Laird Nelson
fuente

Respuestas:

12

cuando bloqueo explícitamente una fila o una tabla, ¿estoy empleando exactamente las mismas construcciones que usan las instalaciones de transacción de la base de datos debajo de las cubiertas para que la transacción funcione correctamente?

Si. Si eso no fuera cierto, entonces su propio 'bloqueo' solo se aplicaría a otro 'bloqueo' similar y no interactuaría con el propio bloqueo del motor. Por lo tanto, bloquearía una fila en una tabla para que no pueda ser bloqueada por otra aplicación de la misma manera, pero el motor mismo ignorará su bloqueo. Estas semánticas rara vez se desean. La mayoría de las veces una aplicación que bloquea una fila significa 'bloquearla contra cualquier medio de acceso / modificación'. Nota al margen de que los mecanismos de bloqueo que son estrictamente específico de la aplicación hacen existe, porque son útiles. Por ejemplo, SQL Server tiene bloqueos de aplicaciones .

Se me ocurre que para que una transacción sea atómica y aislada, debe estar bloqueándose.

El bloqueo es un medio para lograr esto. La alternativa principal es el versionado. Hoy en día, la mayoría de las bases de datos admiten ambas (lo que también significa que si 'bloquea' una fila en la aplicación pero otra transacción usa el control de versiones para leer la fila, lo leerá porque su bloqueo no bloquea las lecturas versionadas).

Está dando vueltas alrededor de un concepto conocido en el mundo de implementación de bases de datos como 'protocolo de bloqueo de dos fases' . El artículo de Wikipedia vinculado es un buen comienzo. Si desea leer una explicación más detallada sobre este tema, le recomiendo que se dirija a la biblioteca y solicite un préstamo sobre Procesamiento de transacciones: conceptos y técnicas . Casi todas las bases de datos que existen son, en esencia, una implementación de ese libro.

Remus Rusanu
fuente
Quizás pueda agregar sobre el control de concurrencia optimista
ypercubeᵀᴹ
¡Ajá! Ahora estamos hablando. De hecho, acechando en el fondo de mi mente estaba MVCC . Gracias por la respuesta bien articulada, las excelentes referencias y por tomarse el tiempo para profundizar en mi pregunta.
Laird Nelson el
3

Algunos antecedentes antes de responder sus preguntas:

Nota: Esto está relacionado con Microsoft SQL Server - RDBMS ........

  • En términos muy simples, una transacción es una secuencia de trabajo que debe realizarse como una sola unidad lógica en su totalidad y debe mantener las propiedades ACID.
  • Cualquier RDBMS debe proporcionar "instalaciones de bloqueo" que se puedan utilizar para completar la transacción en su totalidad, preservando el aislamiento de la transacción y su durabilidad. Esto asegura la integridad física de la base de datos.
  • Lo más importante, por defecto, las transacciones se gestionan a nivel de conexión. Entonces, cuando se inicia una transacción en una conexión, todas las declaraciones T-SQL (S / I / U / D) ejecutadas en esa conexión son parte de la transacción hasta que finaliza la transacción. ( MARS se maneja de manera diferente)

Ahora volviendo a sus preguntas:

cuando bloqueo explícitamente una fila o una tabla, ¿estoy empleando exactamente las mismas construcciones que usan las instalaciones de transacción de la base de datos debajo de las cubiertas para que la transacción funcione correctamente?

Si. Esto significa que debe tener cuidado al determinar la secuencia de datos que se modificará y que dejará la base de datos en un estado coherente. En otras palabras, su operación DML debe dejar la base de datos en un estado consistente que se limite a las reglas comerciales de su organización. Aún así, el RDBMS (aquí SQL Server) puede imponer la integridad física de la transacción.

Desde BOL: El bloqueo y el control de versiones de filas evitan que los usuarios lean datos no confirmados y evitan que varios usuarios intenten cambiar los mismos datos al mismo tiempo. Sin el bloqueo o el control de versiones de fila, las consultas ejecutadas contra esos datos podrían producir resultados inesperados al devolver datos que aún no se han confirmado en la base de datos.

¿Es este bloqueo iniciado por transacción, oculto por transacción, el mismo tipo de bloqueo al que varias bases de datos me permiten acceder a través de construcciones como SELECT FOR UPDATE o comandos de BLOQUEO explícito?

Todo en el servidor SQL está contenido en una transacción. Es cuando accede a sus datos, el RDBMS tiene que tomar bloqueos dependiendo del nivel de aislamiento y las operaciones que está realizando en sus datos. Mira esta respuesta para más detalles.

Algunas buenas referencias:

Kin Shah
fuente
2

Yo diría que las transacciones son parte de la "interfaz" de la base de datos, en cierto sentido, es que usted, como desarrollador, decide cuándo comenzar, finalizar, qué hacer dentro del alcance de las transacciones, etc. Los bloqueos, como los veo, pertenecen a los detalles de implementación y se usa para la sincronización de acceso a diferentes objetos. En la mayoría de los casos, el motor mismo decide qué y durante cuánto tiempo debe bloquearse. Hay muchos bloqueos a nivel del sistema que no se pueden manipular directamente (por ejemplo, el motor puede bloquear ciertas áreas de memoria). Incluso cuando se trata de bloqueos DML, muchos de ellos ocurren detrás de escena (por ejemplo, para garantizar la integridad referencial de Oracle y, por lo que recuerdo, SQLServer puede poner un bloqueo en la fila correspondiente en la tabla maestra si se inserta un nuevo registro en tabla de detalles) como resultado de las declaraciones DML emitidas dentro de la transacción.

Cuando se trata de transacciones, puede esperar un comportamiento más o menos consistente de cualquier RDMS que afirme cumplir con SQL y admitir transacciones, pero cuando se trata de bloqueos, casi todos los proveedores usan diferentes estrategias y terminología. La parte común en todos los RMDS, por lo que puedo decir, es que la concurrencia entre transacciones se define por nivel de aislamiento, mientras que la concurrencia entre bloqueos está controlada por tipos de bloqueo (compartido, exclusivo, etc.)

En resumen, los bloqueos son mecanismos de bajo nivel para controlar la consistencia de los objetos y la concurrencia. Se pueden emitir bloqueos durante la ejecución de sentencias SQL. Depende de la implementación del nivel de aislamiento de la transacción, el motor puede poner diferentes tipos de bloqueos en los objetos afectados (filas, grupo de filas, índices, etc.). Hay un número limitado de comandos disponibles para emitir bloqueos manualmente ( SELECT FOR UPDATE, LOCK). Los bloqueos DML se pueden escalar (depende de RDMS, por ejemplo, en SQLServer fila-> página-> partición-> tabla). El motor de la base de datos también puede emitir bloqueos durante el inicio de la conexión, las copias de seguridad, la restauración, el procedimiento / desencadenador / función / etc.compilación, arranque, paradas, etc.

No estoy seguro de si eso responde a su pregunta, pero espero que tenga sentido.

a1ex07
fuente
Gracias por tu comentario. Definitivamente eres el más cercano hasta ahora. Todavía estoy tratando de ver si las transacciones siempre se implementan en términos de bloqueos que se utilizan, por ejemplo, explícitos LOCKo SELECT FOR UPDATEdeclaraciones, o mediante algún otro mecanismo.
Laird Nelson el
Hasta donde yo sé, en BEGIN TRANSACTIONsí mismo no emite bloqueos. Los bloqueos aparecerán después de los DML dentro de la transacción.
a1ex07
Aclaración: quise decir BEGIN TRANSACTIONque no crea bloqueos DML; se debe en cuestión de hecho algunos bloqueos internos porque tiene que asignar recursos, añadir una entrada en la tabla de sistema [s] (si los hay) que mantiene transacciones activas, etc.
a1ex07
1

Usaré la jerga de SQL Server, pero los conceptos deberían ser los mismos para otros proveedores:

Cada comando que ejecuta se ejecuta dentro de una transacción. Esa transacción puede abrirse explícitamente con BEGIN TRAN, o implícitamente, por el motor de la base de datos. La razón por la que se abre una transacción implícita es que el motor aún necesita mantener el cumplimiento de ACID y la capacidad de una reversión.

Cuando hace un SELECCIONAR PARA ACTUALIZAR, solo significa que mientras la transacción esté en su lugar, mantendrá un cierto bloqueo.

Matan Yungman
fuente
Gracias por tu comentario. Eso lo sé. Pero mi pregunta sigue siendo: cuando se abre esa transacción, ¿se logra su aislamiento manteniendo cerraduras propias? Si es así, ¿son esos bloqueos los mismos tipos de bloqueos que puedo adquirir explícitamente? ¿O la transacción logra el aislamiento por otros medios?
Laird Nelson el
2
Sí, este es el mismo mecanismo. El aislamiento se logra utilizando bloqueos en ambos modos, los mismos bloqueos que puede adquirir explícitamente. La diferencia es que si no abre explícitamente una transacción, los bloqueos se liberarán cuando finalice el comando, mientras que en una transacción explícita los bloqueos se mantienen hasta que se confirme (no es 100% exacto debido a los niveles de aislamiento, pero ese es el Idea general).
Matan Yungman el
Gracias por tu comentario. La razón por la que hago mi pregunta es que leí en alguna parte que algunas bases de datos usan MVCC como medio para lograr transacciones ACID, lo que me parece una forma libre de bloquearlo. En tales casos, entonces, no tengo claro cuándo querría emitir un bloqueo explícitamente. Pero esa es probablemente una pregunta separada. :-)
Laird Nelson
@LairdNelson es el nivel de aislamiento de instantáneas para SQL Server. Existe, pero no es el mecanismo predeterminado para la concurrencia. Sin embargo, es el valor predeterminado para Oracle o Postgresql, IIRC.
Marian
0

El bloqueo es necesario y hacen la base de datos. Esto evita que los datos se corrompan o invaliden cuando varios usuarios intentan leer mientras otros escriben en la base de datos. El aislamiento transaccional generalmente se implementa bloqueando todo lo que se accede en una transacción. Las malas aplicaciones de diseño hacen un gran uso del concepto de bloqueo de la base de datos :) !! Por lo tanto, para evitar el bloqueo, concéntrese en su FK y el diseño de datos.

Se trata de ACID: ¡ lee esto y te aclarará la mente! ACID es un conjunto de propiedades que le gustaría aplicar al modificar una base de datos.

  • **Atomicidad
  • Consistencia
  • Aislamiento
  • Durabilidad**

Una transacción es un conjunto de cambios relacionados que se utiliza para lograr algunas de las propiedades de ACID. Las transacciones son herramientas para lograr las propiedades ACID.

Atomicidad significa que puede garantizar que todas las transacciones sucedan, o ninguna de ellas sucede; puede realizar operaciones complejas como una sola unidad, todo o nada, y un bloqueo, falla de energía, error o cualquier otra cosa no le permitirá estar en un estado en el que solo se hayan producido algunos de los cambios relacionados.

La coherencia significa que usted garantiza que sus datos serán consistentes; Ninguna de las restricciones que tenga sobre los datos relacionados será violada.

El aislamiento significa que una transacción no puede leer datos de otra transacción que aún no se ha completado. Si dos transacciones se ejecutan simultáneamente, cada una verá el mundo como si se ejecutara secuencialmente, y si una necesita leer datos escritos por otra, tendrá que esperar hasta que la otra termine.

La durabilidad significa que una vez que se completa una transacción, se garantiza que todos los cambios se hayan registrado en un medio duradero (como un disco duro), y el hecho de que la transacción se haya completado también se registra.

Entonces, las transacciones son un mecanismo para garantizar estas propiedades; son una forma de agrupar acciones relacionadas de manera tal que, en conjunto, un grupo de operaciones puede ser atómico, producir resultados consistentes, aislarse de otras operaciones y registrarse de forma duradera.

Up_One
fuente
Gracias por tu comentario. Soy al menos consciente de las propiedades de ACID. Lo que aún no tengo claro es: ¿las transacciones implementan ACID usando los mismos tipos de bloqueos que puedo usar directamente a través de LOCKdeclaraciones explícitas , o lo hacen usando algún otro mecanismo?
Laird Nelson el
Las bases de datos ofrecen varios niveles de aislamiento de transacciones, que controlan el grado de bloqueo que se produce al seleccionar datos. Lecturas serializables, repetibles, lectura comprometida, lectura no comprometida.
Up_One