SELECT ... FOR UPDATE
โปรดช่วยให้ฉันเข้าใจที่อยู่เบื้องหลังกรณีการใช้งาน
คำถามที่ 1ต่อไปนี้เป็นตัวอย่างที่ดีว่าSELECT ... FOR UPDATE
ควรใช้เมื่อใด?
ได้รับ:
- ห้อง [ID]
- แท็ก [id, name]
- room_tags [room_id, tag_id]
- room_id และ tag_id เป็นคีย์ต่างประเทศ
แอปพลิเคชันต้องการแสดงรายการห้องทั้งหมดและแท็ก แต่ต้องแยกความแตกต่างระหว่างห้องที่ไม่มีแท็กกับห้องที่ถูกลบออก หากไม่ได้ใช้ SELECT ... FOR UPDATE สิ่งที่อาจเกิดขึ้นคือ:
- ในขั้นต้น:
- ห้องประกอบด้วย
[id = 1]
- แท็กประกอบด้วย
[id = 1, name = 'cats']
- room_tags ประกอบด้วย
[room_id = 1, tag_id = 1]
- ห้องประกอบด้วย
- หัวข้อที่ 1:
SELECT id FROM rooms;
returns [id = 1]
- หัวข้อที่ 2:
DELETE FROM room_tags WHERE room_id = 1;
- หัวข้อที่ 2:
DELETE FROM rooms WHERE id = 1;
- หัวข้อที่ 2: [ทำธุรกรรม]
- หัวข้อที่ 1:
SELECT tags.name FROM room_tags, tags WHERE room_tags.tag_id = 1 AND tags.id = room_tags.tag_id;
- ส่งคืนรายการว่าง
ตอนนี้กระทู้ 1 คิดว่าห้อง 1 ไม่มีแท็ก แต่ในความเป็นจริงห้องนั้นถูกลบออกไปแล้ว เพื่อแก้ปัญหานี้เธรด 1 ควรSELECT id FROM rooms FOR UPDATE
ป้องกันเธรด 2 จากการลบออกrooms
ไปจนกว่าเธรด 1 จะเสร็จสิ้น ถูกต้องหรือไม่
คำถามที่ 2 : เมื่อใดควรใช้SERIALIZABLE
การแยกธุรกรรมเทียบREAD_COMMITTED
กับSELECT ... FOR UPDATE
?
คำตอบคาดว่าจะพกพาได้ (ไม่ใช่เฉพาะฐานข้อมูล) หากไม่สามารถทำได้โปรดอธิบายสาเหตุ
REPEATABLE_READ
และREAD_COMMITTED
ตัวเลือกพกพาหรือไม่? ผลลัพธ์เดียวที่ฉันได้รับสำหรับเซิร์ฟเวอร์ MSSQL
READ COMMITTED
โหมดไม่ได้กำหนดว่าคุณจะเห็นบันทึกที่ทำธุรกรรมโดยธุรกรรมอื่นจริงหรือไม่ แต่ทำให้แน่ใจว่าคุณจะไม่เห็นระเบียนที่ไม่ถูกผูกมัด
select ... for update
on rooms
ยังคงอนุญาตให้room_tags
ลบได้เนื่องจากเป็นตารางแยกกัน คุณหมายถึงถามว่าfor update
ประโยคจะป้องกันการลบrooms
หรือไม่?