Lock for SELECT so another process doesn't get old data

不打扰是莪最后的温柔 提交于 2019-11-29 07:11:12

Your question, referencing an unknown source:

I looked into row locking, but it says you cannot prevent select statements which sounds like it won't work for my condition here. Is my only option to use advisory locks?

The official documentation on the matter:

Row-level locks do not affect data querying; they block only writers and lockers to the same row.

Concurrent attempts will not just select but try to take out the same row-level lock with SELECT ... FOR UPDATE - which causes them to wait for any previous transaction holding a lock on the same row to either commit or roll back. Just what you wanted.

However, many use cases are better solved with advisory locks - in versions before 9.5. You can still lock rows being processed with FOR UPDATE additionally to be safe. But if the next transaction just wants to process "the next free row" it's often much more efficient not to wait for the same row, which is almost certainly unavailable after the lock is released, but skip to the "next free" immediately.

In Postgres 9.5+ consider FOR UPDATE SKIP LOCKED for this. Like @Craig commented, this can largely replace advisory locks.

Related question stumbling over the same performance hog:

Explanation and code example for advisory locks or FOR UPDATE SKIP LOCKED in Postgres 9.5+:

To lock many rows at once:

What you want is the fairly-common SQL SELECT ... FOR UPDATE. The Postgres-specific docs are here.

Using SELECT FOR UPDATE will lock the selected records for the span of the transaction, allowing you time to update them before another thread can select.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!