锁定SELECT,因此另一个进程不会获取旧数据

Bry*_*anP 6 postgresql concurrency locking postgresql-9.3

我有一个表可以有两个线程从中读取数据.如果数据处于某种状态(让我们说状态为1),则该过程将执行某些操作(与此问题无关),然后将状态更新为2.

在我看来,可能存在这样的情况:线程1和线程2都在彼此的微秒内执行选择,并且都看到该行处于状态1,然后两者都执行相同的操作并且在锁具有之后发生2次更新被释放了.

问题是:有没有办法阻止第二个线程能够在Postgres中修改这些数据 - AKA SELECT在第一个线程的锁定被释放后被强制执行另一个更新,因此它知道要保释以防止愚弄?

我查看了行锁定,但是它说你无法阻止选择语句,听起来这对我的条件不起作用.我唯一的选择是使用咨询锁吗?

Erw*_*ter 7

您的问题,引用未知来源:

我查看了行锁定,但是它说你无法阻止选择语句,听起来这对我的条件不起作用.我唯一的选择是使用咨询锁吗?

关于此事的官方文件:

行级锁不会影响数据查询; 他们只阻止作家和储物柜到同一行.

并发尝试不仅会选择,而是尝试取出相同的行级锁定SELECT ... FOR UPDATE- 这会导致它们等待同一行上持有锁定的任何先前事务提交或回滚.正是你想要的.

但是,使用咨询锁可以更好地解决许多用例- 在9.5之前的版本中.您仍然可以锁定正在处理的行FOR UPDATE,以确保安全.但是如果下一个事务只想处理"下一个自由行",那么等待同一行通常更有效率,这在释放锁之后几乎肯定是不可用的,但是立即跳到"下一个空闲".

在Postgres 9.5+中考虑FOR UPDATE SKIP LOCKED这一点.就像@Craig评论的那样,这可以在很大程度上取代咨询锁.

相关问题磕磕绊绊的同一性能猪:

咨询锁或FOR UPDATE SKIP LOCKEDPostgres 9.5+中的解释和代码示例:

一次锁定多行:

  • 请注意,在9.5中,您可以使用"FOR UPDATE SKIP LOCKED"来代替使用建议锁来实现排队.http://michael.otacoo.com/postgresql-2/postgres-9-5-feature-highlight-skip-locked-row-level/.方式更容易. (2认同)