我使用PostgreSQL作为作业队列。以下是检索作业并更新其状态的查询:
UPDATE requests AS re
SET
started_at = NOW(),
finished_at = NULL
FROM (
SELECT
_re.*
FROM requests AS _re
WHERE
_re.state = 'pending'
AND
_re.started_at IS NULL
LIMIT 1
FOR UPDATE SKIP LOCKED
) AS sub
WHERE re.id = sub.id
RETURNING
sub.*
现在,我有几台机器,在每台机器上我有一个进程和几个线程,在每个线程上我有一个工人。同一进程中的所有工作人员共享一个连接池,通常有10-20个连接。
问题是,上面的查询会多次返回一些行!
我找不到任何理由。有人能帮忙吗?
更详细地说,我使用的是Python3和psycopg2。
更新:
我试过@a_horse_with_no_name的回答,但似乎不起作用。
我注意到,一个请求由两个查询检索,其中start\u在
更新为:
2016-04-21 14:23:06.970897 08
和
2016-04-21 14:23:06.831345 08
它们只相差0.14
我想知道在这两个连接执行内部SELECT子查询时,是否两个锁都还没有建立?
更新:
更准确地说,我在一台机器上的一个进程中有200个工人(即200个线程)。
有可能在select时尚未发出锁定事务,或者在select结果就绪且update语句开始时锁丢失。您是否尝试过显式启动事务?
BEGIN;
WITH req AS (
SELECT id
FROM requests AS _re
WHERE _re.state = 'pending' AND _re.started_at IS NULL
LIMIT 1 FOR UPDATE SKIP LOCKED
)
UPDATE requests SET started_at = NOW(), finished_at = NULL
FROM req
WHERE requests.id = req.id;
COMMIT;
还请注意,如果您不想让每个线程互相妨碍,那么每个线程都有自己的连接是很重要的。
如果应用程序使用多个执行线程,则它们不能同时共享连接。您必须显式控制对连接的访问(使用互斥)或为每个线程使用连接。如果每个线程使用自己的连接,则需要使用AT子句指定线程将使用的连接。
来自:http://www.postgresql.org/docs/9.5/static/ecpg-connect.html
如果两个线程共享同一个连接,所有类型的wierd事件都会发生。我相信你的情况就是这样。如果使用一个连接进行锁定,则使用同一连接的所有其他线程都可以访问锁定的对象。
请允许我提出另一种方法,这非常简单。使用redis作为队列。您可以简单地使用redis-py和lush/rpops方法,也可以使用python-rq。
问题内容: 我有一个ListView子类,当上下文操作栏(CAB)处于活动状态时,我可以对其进行选择。CAB设置为事件的回调: 很好,并且ListView可以按预期工作,当前选中的项目在触摸时保持突出显示。 当我关闭CAB时, 我希望ListView返回正常状态(即Touch模式) 。问题是,无论我尝试清除哪种方法,最后选择的项目都会无限期突出显示: 有什么建议? 问题答案: 出现此问题的主要原因
这是我的伪代码: 我想问,如果条件等于“key”的行已经被删除,那么“select for update”阻止的锁是否可以自动解锁,这意味着如果另一个进程在此点进入并选择相同的“key”,它就不能被此进程阻止?
我想调用一个函数时,选择的任何选项。类似于这样: 但不知何故不起作用。有人能帮忙吗。 请注意 我不想捕获更改事件,如果我选择已经选择选项,则不会触发更改事件
假设我们有一个包含许多列的数据框,。我只想创建一个包含以下列的DF
本文向大家介绍pandas 选择重复,包括了pandas 选择重复的使用技巧和注意事项,需要的朋友参考一下 示例 如果需要将值设置0为column B,则在columnA中的重复数据中,首先使用创建掩码Series.duplicated,然后使用DataFrame.ix或Series.mask: 如果需要反面罩使用~:
问题内容: 如何在数据库中选择一些记录,从而跳过MS Access中的行数。在MySQL中是。火鸟是等。 在Google上根本没有运气=( 问题答案: 如果您知道要跳过多少条记录,则可以执行以下操作: 然后,您可以排除不需要的记录。 如果您随后知道要返回的记录总数,则可以执行以下操作: