Por favor me ajude a entender o caso de uso por trás SELECT ... FOR UPDATE
.
Pergunta 1 : O seguinte é um bom exemplo de quando SELECT ... FOR UPDATE
deve ser usado?
Dado:
- quartos [id]
- tags [id, nome]
- room_tags [room_id, tag_id]
- room_id e tag_id são chaves estrangeiras
O aplicativo deseja listar todas as salas e suas marcas, mas precisa diferenciar as salas sem marcas das salas que foram removidas. Se SELECT ... FOR UPDATE não for usado, o que pode acontecer é:
- Inicialmente:
- quartos contém
[id = 1]
- tags contém
[id = 1, name = 'cats']
- room_tags contém
[room_id = 1, tag_id = 1]
- quartos contém
- Tópico 1:
SELECT id FROM rooms;
returns [id = 1]
- Tópico 2:
DELETE FROM room_tags WHERE room_id = 1;
- Tópico 2:
DELETE FROM rooms WHERE id = 1;
- Tópico 2: [confirma a transação]
- Tópico 1:
SELECT tags.name FROM room_tags, tags WHERE room_tags.tag_id = 1 AND tags.id = room_tags.tag_id;
- retorna uma lista vazia
Agora, o Tópico 1 pensa que a sala 1 não tem etiquetas, mas na realidade a sala foi removida. Para resolver este problema, o Tópico 1 deve SELECT id FROM rooms FOR UPDATE
, evitando assim que o Tópico 2 exclua derooms
até que o Thread 1 seja concluído. Isso está correto?
Pergunta 2 : Quando se deve usar o SERIALIZABLE
isolamento de transação versus READ_COMMITTED
comSELECT ... FOR UPDATE
?
Espera-se que as respostas sejam portáteis (não específicas do banco de dados). Se isso não for possível, explique o porquê.
REPEATABLE_READ
e READ_COMMITTED
até opções portáteis? Os únicos resultados que obtenho são para o servidor MSSQL
READ COMMITTED
modo não define se você verá ou não registros confirmados por outra transação: isso apenas garante que você nunca verá registros não confirmados.
select ... for update
on rooms
ainda permitirá room_tags
a exclusão porque são tabelas separadas. Você quis dizer se a for update
cláusula impedirá exclusões de rooms
?