EF Core 8结合PostgreSQL实现悲观行锁的技术问题咨询
悲观锁在EF Core+PostgreSQL中的行为与EF原生支持方案
需求
- Worker处理数据项时,对目标行应用悲观锁,同时允许其他Worker处理同表中的其他数据项。
当前实现与生成SQL
使用EF Core结合原生SQL实现锁逻辑:
dbContext.dbSet.FromSqlRaw("""select * from schema."table" FOR UPDATE SKIP LOCKED""")
后续通过Linq to EF链式添加过滤、分页等子句后,EF会将原生SQL作为子查询包裹,生成的最终SQL示例如下:
select f."C1", f."C2", f."C3" from ( select * from schema."tablename" FOR UPDATE SKIP LOCKED ) as f where f."C4" = 'whatever' limit 3
测试中的异常行为
存在对全表锁的担忧,o1-preview验证了该疑虑,但pgAdmin测试结果存在不一致:
- 无外层ORDER BY场景:开启事务执行第一个查询并保持未提交,并行执行多个相同查询时,每组返回3条未被锁定的连续行,外层的过滤、关联操作不影响锁机制,符合预期;
- 外层添加ORDER BY场景:第一个查询返回3行后,第二个查询无法获取任何数据;但将
ORDER BY移至内层子查询时,锁机制恢复正常。
疑问
- 是否有权威文档明确说明不同场景下
FOR UPDATE SKIP LOCKED锁机制的预期行为? - 有没有无需编写原生SQL,直接通过EF Core API添加
FOR UPDATE SKIP LOCKED锁提示的方法?
2024.12.12 更新
已使用EF Core拦截器框架创建了一个工具库,可覆盖大多数场景需求(至少满足自身业务场景),但受限于拦截器的功能边界,该库并非完全无缺陷。后续会持续测试,可能将其公开发布。
内容的提问来源于stack exchange,提问作者ZorgoZ
相关产品推荐
相关产品推荐

