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
enMySQL
(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 queDML
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 queSELECT
oDELETE
la consulta se bloqueará hasta que se confirme otra sesión. -
En bases de datos que usan
MVCC
(comoOracle
,PostgreSQL
,MySQL
conInnoDB
), unDML
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, unSELECT FOR UPDATE
sería útil:bloquearíaSELECT
o elDELETE
consulta hasta que se confirme otra sesión, al igual queSQL 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 anterioresPostgreSQL
versiones,REPEATABLE READ
es 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 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 conSELECT FOR UPDATE
-
En
InnoDB
,REPEATABLE READ
ySERIALIZABLE
son cosas diferentes:lectores enSERIALIZABLE
establece bloqueos de tecla siguiente en los registros que evalúan, evitando efectivamente elDML
concurrente en ellos. Entonces no necesita unSELECT FOR UPDATE
en modo serializable, pero los necesita enREPEATABLE READ
oREAD 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".