请帮助我了解后面的用例SELECT ... FOR UPDATE
。
问题1:以下是何时SELECT ... 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.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
对rooms
将仍然允许room_tags
被删除,因为它们是独立的表。您是否要问该for update
条款是否会阻止从中删除rooms
?