我可以获取一个 postgresql 锁来防止对 table 的一部分进行并发插入吗?

Can I obtain a postgresql lock that prevents concurrent inserts for a portion of a table?

我有一个 roomsusers 的连接 table attendees,其中有一个额外的列表示随机分配的字符串(来自字符串池中)。

我想防止同时进入的两个用户不小心分配了相同的字符串——所以我希望用户 B 等待查找以前的用户在房间(及其分配的字符串)中,直到用户 A 完成插入 - 但我不想做 table 锁,因为行插入说 room_id = 12 不会影响插入room_id = 77.

我无法使用唯一约束来解决这个问题,因为在一个房间中有大量用户的情况下可能会出现重复的字符串(字符串会重新分配)一旦所有这些都被使用一次)。*

我猜是在做类似

的事情

SELECT room_id, user_id, random_string WHERE room_id = ? FOR UPDATE

不会有帮助,因为它不会阻止用户 B 进行插入——即使 SELECT FOR UPDATE 阻止用户 B 进行相同的调用以读取与该房间对应的行,如果用户 A 和用户 B 都是第一个加入的用户(并且没有任何行供 room_id 锁定)会怎样?

我会使用在 room_id 上键入的咨询锁吗?如果我有多个并发写入(例如,用户 A 应该首先完成,然后是用户 B,然后是用户 C),这仍然有帮助吗?

*以下是为什么字符串不一定唯一的示例:假设字符串池是 "red", "blue", "green"——前三个进入的用户每人随机分配一个,然后池重置.接下来的三个用户也是随机分配的,因此对于房间中的六个用户,正好有两个 "red"、两个 "blue" 和两个 "green".

在 SO 上令人沮丧的几天后,我最终在 Reddit 上得到了解决问题的有用回复:

rooms table 使用 SELECT FOR UPDATE 查询,锁定与房间对应的行,直到第一个用户的交易完成。