Xin hãy giúp tôi hiểu trường hợp sử dụng phía sau SELECT ... FOR UPDATE
.
Câu hỏi 1 : Đây có phải là một ví dụ tốt về thời điểm SELECT ... FOR UPDATE
nên sử dụng?
Được:
- phòng [id]
- thẻ [id, tên]
- room_tags [room_id, tag_id]
- room_id và tag_id là khóa ngoại
Ứng dụng muốn liệt kê tất cả các phòng và thẻ của họ, nhưng cần phân biệt giữa các phòng không có thẻ so với các phòng đã bị xóa. Nếu CHỌN ... ĐỂ CẬP NHẬT không được sử dụng, điều có thể xảy ra là:
- Ban đầu:
- phòng chứa
[id = 1]
- thẻ chứa
[id = 1, name = 'cats']
- room_tags chứa
[room_id = 1, tag_id = 1]
- phòng chứa
- Chủ đề 1:
SELECT id FROM rooms;
returns [id = 1]
- Chủ đề 2:
DELETE FROM room_tags WHERE room_id = 1;
- Chủ đề 2:
DELETE FROM rooms WHERE id = 1;
- Chủ đề 2: [cam kết giao dịch]
- Chủ đề 1:
SELECT tags.name FROM room_tags, tags WHERE room_tags.tag_id = 1 AND tags.id = room_tags.tag_id;
- trả về một danh sách trống
Bây giờ Chủ đề 1 nghĩ rằng phòng 1 không có thẻ, nhưng thực tế phòng đã bị xóa. Để giải quyết vấn đề này, Thread 1 nên SELECT id FROM rooms FOR UPDATE
, do đó ngăn chặn Thread 2 xóa từ rooms
cho đến khi Thread 1 được thực hiện. Đúng không?
Câu 2 : Khi nào nên sử dụng SERIALIZABLE
cách ly giao dịch so READ_COMMITTED
với SELECT ... FOR UPDATE
?
Câu trả lời dự kiến sẽ có thể mang theo (không phải cơ sở dữ liệu cụ thể). Nếu điều đó là không thể, xin vui lòng giải thích tại sao.
REPEATABLE_READ
và READ_COMMITTED
thậm chí tùy chọn di động? Kết quả duy nhất tôi nhận được cho những người đó là cho máy chủ MSSQL
READ COMMITTED
chế độ không xác định liệu bạn có thực sự nhìn thấy các bản ghi được cam kết bởi một giao dịch khác hay không: nó chỉ đảm bảo bạn sẽ không bao giờ thấy các bản ghi không được cam kết.
select ... for update
trên rooms
vẫn sẽ cho phép room_tags
được xóa bởi vì họ là các bảng riêng biệt. Bạn có nghĩa là hỏi liệu for update
điều khoản sẽ ngăn chặn xóa rooms
?