2012-09-12 38 views
0

我有一个扭曲的守护进程,它执行一些xml提要解析。用扭曲的Python锁定Postgres表

我存储我的数据在PostgreSQL中通过twisted.enterprise.adbapi,这是IIRC包装psycopg2

我碰到与将数据存储到数据库中的几个问题 - 在那里重复数据定期得到。

说实话,我的实施有一些潜在的问题,应该重做和设计好得多。虽然我缺乏时间和资源 - 所以我们现在只是“保持运行”模式。

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

由于我认为功能的简要概述是错误的:

扭曲查询的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 

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

我认为这可能会被修复 - 或者至少被排除作为一个问题 - 如果我把这个快速部分封装在独占表锁中。

虽然以前我从来没有通过扭曲表锁。任何人都可以将我指向正确的方向吗?

回答

1

您可以执行SELECT FOR UPDATE而不是普通的SELECT,这将锁定查询返回的行。如果你真的想锁定,你可以发出LOCK声明,但基于你的问题的其余部分,我想你想要行锁定。

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

但是,锁定可能不是你的问题。首先,如果您混合deferToThreadadbapi,则可能是错误的。 adbapi已经在为做相应的deferToThread你。你应该能够在主线程上做所有事情。

尽管您需要包含一个具有代表性的例子,考虑一下你的问题:它基本上是“有时我得到重复的数据,有一个自我承认的有问题的实现,这很大,我不能修复,我也不能给你看。”这不是一个可以回答的问题。

+0

谢谢。 1.我将执行select for update。 2.我会阅读runInteraction –

+0

完整的“感谢”没有通过评论。是的,问题可能会更好 - 但我不得不重新格式化200多行代码来表达这一点。所以我应该在另一个问题上这样做。 –