如何在postgres中使用'For update skip locked'而不锁定查询中使用的所有表中的行?

问题描述:

当你想使用的Postgres的SELECT FOR UPDATE SKIP已锁定的功能,以确保两个不同的用户从表中读取,并声称任务不要被对方阻止,也没有得到已经被其他用户读取任务:如何在postgres中使用'For update skip locked'而不锁定查询中使用的所有表中的行?

正在查询中使用连接来检索任务。除了包含主要信息的表以外,我们不希望任何其他表具有行级锁定。示例查询下面 - 在下面的查询

SELECT v.someid , v.info, v.parentinfo_id, v.stage FROM task v, parentinfo pi WHERE v.stage = 'READY_TASK' 
      AND v.parentinfo_id = pi.id 
      AND pi.important_info_number = ( 
      SELECT MAX(important_info_number) FROM parentinfo) 
       ORDER BY v.id limit 200 for update skip locked; 

现在如果用户A检索这个表的一些200行,用户B应该能够检索另一组的200只锁定在表-'task行”行。

编辑:按照下面的评论,查询将改为:

SELECT v.someid , v.info, v.parentinfo_id, v.stage FROM task v, parentinfo pi WHERE v.stage = 'READY_TASK' 
      AND v.parentinfo_id = pi.id 
      AND pi.important_info_number = ( 
      SELECT MAX(important_info_number) FROM parentinfo) ORDER BY v.id limit 200 for update of v skip locked; 

如何最好地利用这样的地方以便行排序?虽然如果多个用户调用此命令,订单就会受到影响,但仍然应该保留正在返回的行的某种顺序。

另外,这是否也确保多个线程调用相同的select查询将检索一组不同的行或仅锁定更新命令?

+4

[Doc](https://www.postgresql.org/docs/9.5/static/sql-select.html):“'FOR lock_strength [OF table_name [,...]] [NOWAIT | SKIP LOCKED] '...如果在锁定子句中命名了特定的表,那么只有来自这些表的行才会被锁定;在SELECT中使用的其他任何表都会照常读取。“ – Abelisto

刚刚尝试了这一点 - 多选择查询将最终检索不同的行集。此外,按顺序确保获得最终结果的顺序。