SELECT ... FOR UPDATE
的用例。问题1:以下是否是使用
SELECT ... FOR UPDATE
的好例子?给定:
房间 [id] 标签 [id, name] 房间标签 [room_id, tag_id]
房间 id 和 标签 id 是外键
应用程序想要列出所有房间及其标签,但需要区分没有标签的房间和已删除的房间。如果不使用 SELECT ... FOR UPDATE,可能会发生以下情况:
最初: 房间包含 [id = 1] 标签包含 [id = 1, name = 'cats'] 房间标签包含 [room_id = 1, tag_id = 1]
线程1:
SELECT id FROM rooms;
返回 [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
事务隔离级别,而不是使用带有SELECT ... FOR UPDATE
的READ_COMMITTED
?
需要提供可移植的答案(非特定于某个数据库)。如果不可能,请解释原因。
rooms
执行的select ... for update
语句仍然允许删除room_tags
,因为它们是独立的表格。您的意思是询问for update
子句是否会防止从rooms
删除内容? - Chris Saxon