基于EXCLUDE约束实现范围读写锁的技术方案问询
解决方案
要实现这种读写锁的约束逻辑,你需要拆分两个独立的排除约束,分别处理写锁之间的冲突和读写锁之间的冲突,读锁之间则不做限制:
1. 移除原有全局约束
首先删除你原来的约束——它会阻止所有范围重叠的记录,不符合多读锁共存的需求:
ALTER TABLE excllock DROP CONSTRAINT IF EXISTS excllock_myrange_key_excl;
2. 添加两个针对性的排除约束
约束1:禁止同一key下存在重叠范围的写锁
这个约束确保同一key下,不会有两个isread=FALSE的行出现范围重叠:
ALTER TABLE excllock ADD CONSTRAINT excllock_write_write_excl EXCLUDE USING gist ( key WITH =, myrange WITH && ) WHERE (NOT isread);
约束2:禁止读写锁之间的范围重叠
这个约束实现读写互斥:当插入写锁时,不能有重叠范围的读锁;插入读锁时,也不能有重叠范围的写锁。这里用isread <> isread作为条件,利用PostgreSQL的约束匹配逻辑——新行的isread值会和已有行的isread值对比,只要两者不同就触发冲突:
ALTER TABLE excllock ADD CONSTRAINT excllock_read_write_excl EXCLUDE USING gist ( key WITH =, myrange WITH && ) WHERE (isread <> isread);
验证效果
现在执行你给出的示例操作,就能得到预期结果:
- 多个读锁可正常插入(无约束限制读锁间重叠)
- 插入写锁时,若已有重叠读锁,会触发
excllock_read_write_excl约束失败 - 已有写锁时,插入重叠范围的读锁或写锁都会触发对应约束失败
- 空闲范围插入写锁可正常执行
内容的提问来源于stack exchange,提问作者winwin
相关产品推荐
相关产品推荐

