sql >> Base de Datos >  >> RDS >> Mysql

¿Cuándo usar SELECCIONAR... PARA ACTUALIZAR?

La única forma portátil de lograr la coherencia entre las habitaciones y las etiquetas y asegurarse de que nunca se devuelvan las habitaciones después de haberlas eliminado es bloquearlas con SELECT FOR UPDATE .

Sin embargo, en algunos sistemas, el bloqueo es un efecto secundario del control de concurrencia y se obtienen los mismos resultados sin especificar FOR UPDATE. explícitamente.

Para resolver este problema, el subproceso 1 debe SELECT id FROM rooms FOR UPDATE , evitando así que Thread 2 se elimine de rooms hasta que el Hilo 1 esté terminado. ¿Es eso correcto?

Esto depende del control de concurrencia que utilice su sistema de base de datos.

  • MyISAM en MySQL (y varios otros sistemas antiguos) bloquea toda la tabla durante la duración de una consulta.

  • En SQL Server , SELECT las consultas colocan bloqueos compartidos en los registros/páginas/tablas que han examinado, mientras que DML las consultas colocan bloqueos de actualización (que luego se promocionan a exclusivos o se degradan a bloqueos compartidos). Los bloqueos exclusivos son incompatibles con los bloqueos compartidos, por lo que SELECT o DELETE la consulta se bloqueará hasta que se confirme otra sesión.

  • En bases de datos que usan MVCC (como Oracle , PostgreSQL , MySQL con InnoDB ), un DML la consulta crea una copia del registro (de una u otra forma) y generalmente los lectores no bloquean a los escritores y viceversa. Para estas bases de datos, un SELECT FOR UPDATE sería útil:bloquearía SELECT o el DELETE consulta hasta que se confirme otra sesión, al igual que SQL Server lo hace.

¿Cuándo se debe usar REPEATABLE_READ? aislamiento de transacciones frente a READ_COMMITTED con SELECT ... FOR UPDATE ?

Generalmente, REPEATABLE READ no prohíbe las filas fantasma (filas que aparecieron o desaparecieron en otra transacción, en lugar de modificarse)

  • En Oracle y anteriores PostgreSQL versiones, REPEATABLE READ es en realidad un sinónimo de SERIALIZABLE . Básicamente, esto significa que la transacción no ve los cambios realizados después de que ha comenzado. Entonces, en esta configuración, el último Thread 1 query devolverá la habitación como si nunca se hubiera eliminado (lo que puede o no ser lo que quería). Si no desea mostrar las salas después de que se hayan eliminado, debe bloquear las filas con SELECT FOR UPDATE

  • En InnoDB , REPEATABLE READ y SERIALIZABLE son cosas diferentes:lectores en SERIALIZABLE establece bloqueos de tecla siguiente en los registros que evalúan, evitando efectivamente el DML concurrente en ellos. Entonces no necesita un SELECT FOR UPDATE en modo serializable, pero los necesita en REPEATABLE READ o READ COMMITED .

Tenga en cuenta que el estándar sobre los modos de aislamiento prescribe que no vea ciertas peculiaridades en sus consultas, pero no define cómo (con bloqueo o con MVCC o de otro modo).

Cuando digo "no necesitas SELECT FOR UPDATE Realmente debería haber agregado "debido a los efectos secundarios de cierta implementación del motor de base de datos".