Ayúdame a comprender el caso de uso subyacente SELECT ... FOR UPDATE
.
Pregunta 1 : ¿Es el siguiente un buen ejemplo de cuándo SELECT ... FOR UPDATE
debe usarse?
Dado:
- habitaciones [id]
- etiquetas [id, nombre]
- room_tags [room_id, tag_id]
- room_id y tag_id son claves externas
La aplicación quiere enumerar todas las habitaciones y sus etiquetas, pero necesita diferenciar las habitaciones sin etiquetas de las habitaciones que se han eliminado. Si SELECT ... FOR UPDATE no se usa, lo que podría suceder es:
- Inicialmente:
- habitaciones contiene
[id = 1]
- etiquetas contiene
[id = 1, name = 'cats']
- room_tags contiene
[room_id = 1, tag_id = 1]
- habitaciones contiene
- Hilo 1:
SELECT id FROM rooms;
returns [id = 1]
- Hilo 2:
DELETE FROM room_tags WHERE room_id = 1;
- Hilo 2:
DELETE FROM rooms WHERE id = 1;
- Hilo 2: [confirma la transacción]
- Hilo 1:
SELECT tags.name FROM room_tags, tags WHERE room_tags.tag_id = 1 AND tags.id = room_tags.tag_id;
- devuelve una lista vacía
Ahora el hilo 1 piensa que la habitación 1 no tiene etiquetas, pero en realidad la habitación se ha eliminado. Para resolver este problema, el hilo 1 debería SELECT id FROM rooms FOR UPDATE
, evitando así que el hilo 2 se elimine rooms
hasta que el hilo 1 esté terminado. ¿Es eso correcto?
Pregunta 2 : ¿Cuándo se debe utilizar el SERIALIZABLE
aislamiento de transacciones frente a READ_COMMITTED
con SELECT ... FOR UPDATE
?
Se espera que las respuestas sean portátiles (no específicas de la base de datos). Si eso no es posible, explique por qué.
REPEATABLE_READ
e READ_COMMITTED
incluso las opciones portátiles? Los únicos resultados que obtengo son para el servidor MSSQL
READ COMMITTED
modo no define si realmente verá o no los registros comprometidos por otra transacción: solo se asegura de que nunca verá registros no confirmados.
select ... for update
on rooms
todavía permitirá room_tags
que se eliminen porque son tablas separadas. ¿Quería preguntar si la for update
cláusula evitará las eliminaciones rooms
?