Tolong bantu saya memahami kasus penggunaan di belakang SELECT ... FOR UPDATE
.
Pertanyaan 1 : Apakah berikut ini contoh yang baik tentang kapan SELECT ... FOR UPDATE
harus digunakan?
Diberikan:
- ruangan [id]
- tag [id, nama]
- room_tags [room_id, tag_id]
- room_id dan tag_id adalah kunci asing
Aplikasi ingin mencantumkan semua ruang dan tag-nya, tetapi perlu membedakan antara ruang tanpa tag versus ruang yang telah dihapus. Jika SELECT ... FOR UPDATE tidak digunakan, yang mungkin terjadi adalah:
- Mulanya:
- ruangan berisi
[id = 1]
- tag berisi
[id = 1, name = 'cats']
- room_tags berisi
[room_id = 1, tag_id = 1]
- ruangan berisi
- Benang 1:
SELECT id FROM rooms;
returns [id = 1]
- Benang 2:
DELETE FROM room_tags WHERE room_id = 1;
- Benang 2:
DELETE FROM rooms WHERE id = 1;
- Thread 2: [melakukan transaksi]
- Benang 1:
SELECT tags.name FROM room_tags, tags WHERE room_tags.tag_id = 1 AND tags.id = room_tags.tag_id;
- mengembalikan daftar kosong
Sekarang Thread 1 mengira bahwa ruangan 1 tidak memiliki tag, tetapi kenyataannya ruangan tersebut telah dihapus. Untuk mengatasi masalah ini, Utas 1 harus SELECT id FROM rooms FOR UPDATE
, dengan demikian mencegah Utas 2 dihapus dari rooms
hingga Utas 1 selesai. Apakah itu benar?
Pertanyaan 2 : Kapan sebaiknya seseorang menggunakan SERIALIZABLE
isolasi transaksi versus READ_COMMITTED
dengan SELECT ... FOR UPDATE
?
Jawaban diharapkan portabel (tidak spesifik database). Jika tidak memungkinkan, jelaskan alasannya.
REPEATABLE_READ
dan READ_COMMITTED
bahkan opsi portabel? Satu-satunya hasil yang saya dapatkan untuk itu adalah untuk server MSSQL
READ COMMITTED
mode tidak menentukan apakah Anda benar-benar akan melihat catatan yang dilakukan oleh transaksi lain: ini hanya memastikan Anda tidak akan pernah melihat catatan yang tidak terikat.
select ... for update
pada rooms
masih memungkinkan room_tags
untuk dihapus karena mereka adalah tabel terpisah. Apakah Anda bermaksud menanyakan apakah for update
klausul akan mencegah penghapusan dari rooms
?