请帮助我了解背后的用例SELECT ... FOR UPDATE
。
问题 1SELECT ... FOR UPDATE
:以下是什么时候应该使用的一个很好的例子吗?
鉴于:
- 房间[id]
- 标签[id,名称]
- 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.room_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
with SELECT ... FOR UPDATE
?
答案应该是可移植的(不是特定于数据库的)。如果这不可能,请解释原因。