PostgreSQL 和锁定

发布于 2024-10-31 19:06:37 字数 267 浏览 1 评论 0原文

希望一些比我更聪明的 DBA 可以帮助我找到一个好的解决方案来完成我需要做的事情。

为了便于讨论,我们假设我有一个名为“work”的表,其中包含一些列,其中一列代表给定客户端对该行工作的所有权。场景是,我将连接 2 个客户端并轮询表以查找要完成的工作,当出现一行(或某些行)时,选择这些行的第一个客户端也会更新它们以暗示所有权,即更新将删除这些行,使其不会返回到任何其他客户端的选择。我的问题是,在这种情况下,我可以使用哪种锁定来防止 2 个客户端同时访问表,并且它们都通过 select 返回相同的行?

Hopefully some smarter DBAs than I can help me find a good solution for what I need to do.

For the sake of discussion, lets assume I have a table called 'work' with some number of columns, one of which is a column that represents ownership of that row of work from a given client. The scenario is that I'll have 2 clients connected and polling a table for work to be done, when a row (or some number of rows) shows up, the first client that selects the rows will also update them to imply ownership, that update will remove those rows from being returned to any other client's selects. My question is, in this scenario, what sort of locking can I use to prevent 2 clients from hitting the table at the same time and both of them being returned the same rows via the select?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

赤濁 2024-11-07 19:06:37

带有 RETURNING 子句的 UPDATE 语句就是执行此操作的方法。

UPDATE table
SET ownership = owner
RETURNING ( column list );

参考文献:

类似问题

文档

The UPDATE statement with RETURNING clause is the way to do this.

UPDATE table
SET ownership = owner
RETURNING ( column list );

REFERENCES:

Similar Question

Documentation

与酒说心事 2024-11-07 19:06:37

我的问题是,在这种情况下,我可以使用哪种锁定来防止 2 个客户端同时访问表,并且它们都通过 select 返回相同的行?

这里不需要锁定。

UPDATE 中,只需指定您只希望脚本在所有者仍为 null 时获取任务的所有权(假设这就是您标记未分配任务的方式)。这应该有效:

UPDATE foo SET owner = ? WHERE id = ? AND owner = ? WHERE owner IS NULL

如果修改的行数等于您预期的数量(或者 RETURNING 子句返回 @Ketema 建议的结果),那么您成功地获得了所有权。


虚假编辑,因为我在提交此答案之前注意到您的评论:

例如:2 个客户端同时发出该查询,他们没有机会操作相同的行?

正确的。您可能想阅读 MVCC。在事务外部运行这些语句将执行正确的操作。事务内的行为会有所不同。

My question is, in this scenario, what sort of locking can I use to prevent 2 clients from hitting the table at the same time and both of them being returned the same rows via the select?

No locking needed here.

In the UPDATE, simply specify that you only want the script to take ownership of the task if the owner is still null (assuming that's how you flag unassigned tasks). This should work:

UPDATE foo SET owner = ? WHERE id = ? AND owner = ? WHERE owner IS NULL

If the number of modified rows is equal to the number you expected (or a RETURNING clause returns results as suggested by @Ketema), then you successfully grabbed ownership.


Fake edit because I noticed your comment mere moments before submitting this answer:

eg: 2 clients issuing that query at the same time, they have no chance of manipulating the same rows?

Correct. You might want to read up on MVCC. Running these statements outside of a transaction will do the right thing. Behavior inside a transaction will be different.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文