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 updateon roomsยังคงอนุญาตให้room_tagsลบได้เนื่องจากเป็นตารางแยกกัน คุณหมายถึงถามว่าfor updateประโยคจะป้องกันการลบroomsหรือไม่?