Estoy tratando de entender cómo funcionan las transacciones y me encontré con un escenario que no tiene mucho sentido para mí. Esperaba que alguien pudiera ayudarme a entenderlo.
tengo dos transacciones
transacción 1
BEGIN; update data set val = val + 1 where id = 1transacción 2
BEGIN; select * from dataTengo dos terminales abiertas, comienzo la primera transacción y ejecuto la consulta de actualización. Esto supuestamente otorga el bloqueo exclusivo a la transacción 1 en la tupla con id 1.
Después de eso, ejecuto la segunda consulta en otra terminal antes de realizar la primera transacción. Esperaba que se detuviera, ya que la primera transacción tiene el bloqueo exclusivo que evitará que esta transacción adquiera el bloqueo de lectura en la tupla con id 1.
Sin embargo, mysql ejecuta la consulta de selección y devuelve los datos "no sucios".
¿Alguien puede darme la explicación detrás de este comportamiento de mysql?
SELECT no requiere un bloqueo de fila compartido de forma predeterminada. Puede leer la versión confirmada más reciente de la fila sin bloquear, mediante el uso de la arquitectura de control de concurrencia de múltiples versiones (MVCC) .
Puede escribir una consulta SELECT que solicite explícitamente un bloqueo , pero sin estas cláusulas de bloqueo, SELECT no requiere bloqueos de fila.
Para tener una visión completa de cómo funcionan las transacciones, creo que tiene sentido tener en cuenta que los bloqueos compartidos se adquieren de manera diferente, según el nivel de aislamiento.
Los bloqueos exclusivos se liberan cuando finaliza la transacción, independientemente del nivel de aislamiento.
La diferencia entre los niveles de aislamiento se refiere a la forma en que se adquieren/liberan los bloqueos compartidos (de lectura).
En el nivel de aislamiento Lectura no confirmada, no se adquieren bloqueos compartidos. Bajo este nivel de aislamiento, puede ocurrir el problema de simultaneidad conocido como "Lecturas sucias".
En el nivel de aislamiento de lectura confirmada, se adquieren bloqueos compartidos para los registros en cuestión. Los bloqueos compartidos se liberan cuando finaliza la instrucción actual. Este nivel de aislamiento evita las "lecturas sucias" pero, dado que el registro puede ser actualizado por otras transacciones simultáneas, pueden ocurrir "lecturas no repetibles" o "lecturas fantasma".
En el nivel de aislamiento de lecturas repetibles, los bloqueos compartidos se adquieren durante la duración de la transacción. Se evitan las "lecturas sucias" y las "lecturas no repetibles", pero aún pueden ocurrir "lecturas fantasma".
En el nivel de aislamiento serializable, los bloqueos compartidos de rango se adquieren durante la duración de la transacción. No se produce ninguno de los problemas de simultaneidad mencionados anteriormente, pero el rendimiento se reduce drásticamente y existe el riesgo de que se produzcan interbloqueos.