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.
-
MyISAMenMySQL(y varios otros sistemas antiguos) bloquea toda la tabla durante la duración de una consulta. -
En
SQL Server,SELECTlas consultas colocan bloqueos compartidos en los registros/páginas/tablas que han examinado, mientras queDMLlas 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 queSELECToDELETEla consulta se bloqueará hasta que se confirme otra sesión. -
En bases de datos que usan
MVCC(comoOracle,PostgreSQL,MySQLconInnoDB), unDMLla 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, unSELECT FOR UPDATEsería útil:bloquearíaSELECTo elDELETEconsulta hasta que se confirme otra sesión, al igual queSQL Serverlo 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
Oracley anterioresPostgreSQLversiones,REPEATABLE READes en realidad un sinónimo deSERIALIZABLE. 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 últimoThread 1query 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 conSELECT FOR UPDATE -
En
InnoDB,REPEATABLE READySERIALIZABLEson cosas diferentes:lectores enSERIALIZABLEestablece bloqueos de tecla siguiente en los registros que evalúan, evitando efectivamente elDMLconcurrente en ellos. Entonces no necesita unSELECT FOR UPDATEen modo serializable, pero los necesita enREPEATABLE READoREAD 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".