我可以获取一个 postgresql 锁来防止对 table 的一部分进行并发插入吗?
Can I obtain a postgresql lock that prevents concurrent inserts for a portion of a table?
我有一个 rooms
和 users
的连接 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
查询,锁定与房间对应的行,直到第一个用户的交易完成。
我有一个 rooms
和 users
的连接 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
查询,锁定与房间对应的行,直到第一个用户的交易完成。