0

我有一个扭曲的守护进程,它可以进行一些 xml 提要解析。

我通过 twisted.enterprise.adbapi 将数据存储在 PostgreSQL 中,IIRC 正在包装 psycopg2

我在将数据存储到数据库时遇到了一些问题——重复数据会定期进入数据库。

老实说,我的实现存在一些潜在的问题,应该重做并设计得更好。不过,我没有时间和资源来做这件事——所以我们现在处于“保持运行”模式。

我认为问题可能来自我对 deferToThread 的使用或我在开始时如何生成服务器。

作为对我认为有问题的功能的快速概述:

Twisted 查询 Postgres 以获取应分析的帐户,并对其设置块

SELECT 
    id 
FROM 
    xml_sources 
WHERE 
    timestamp_last_process < ( CURRENT_TIMESTAMP AT TIME ZONE 'UTC' - INTERVAL '4 HOUR' ) 
    AND
    is_processing_block IS NULL ;

lock_ids = [ i['id'] for i in results ]

UPDATE xml_sources SET is_processing_block = True WHERE id IN %(lock_ids)s

我认为正在发生的事情是(意外地)运行多个服务器或各种其他问题导致多个线程处理这些数据。

我认为如果我将这个快速部分包装在一个独占表锁中,这可能会得到解决——或者至少被排除为一个问题。

不过,我以前从未通过扭曲完成表锁定。谁能指出我正确的方向?

4

1 回答 1

1

您可以执行 aSELECT FOR UPDATE而不是 plain SELECT,这将锁定查询返回的行。如果你真的想要锁定,你可以发出一个LOCK语句,但根据你的其余问题,我认为你想要行锁定。

如果您正在使用adbapi,请记住,runInteraction如果您想在事务中运行多个语句,则需要使用。传递给的函数runInteraction将在一个线程中运行,因此您可能需要使用callFromThreadblockingCallFromThread从数据库交互返回到反应器。

但是,锁定可能不是您的问题。一方面,如果您正在混合deferToThreadadbapi,则可能有问题。 adbapi已经在deferToThread 你做相当于。您应该能够在主线程上执行所有操作。

不过,您必须包含一个具有代表性的示例才能获得更具体的答案。考虑一下您的问题:基本上是“有时我会收到重复的数据,并且执行过程自认存在问题,这很大,我无法修复,也无法向您展示。” 这不是一个可以回答的问题。

于 2012-09-12T23:28:37.227 回答