【问题标题】:Django 1.1 Signals - Strange timing issue with threadDjango 1.1 Signals - 线程的奇怪计时问题
【发布时间】:2012-05-07 19:47:58
【问题描述】:

我有一个模型(PurchaseOrder - 缩写为 PO)持有时间预算。用户可以在此预算中添加小时记录,其中每个小时记录都会减少剩余预算。

我实现了更新剩余预算的信号。添加一小时记录后,预算相应减少。因为计算可能很耗时,所以我为此任务使用了一个线程。

def update_po_remaining_value(sender, instance, **kwargs):
    CalculatePOThread(sender, instance).start()   
post_save.connect(update_po_remaining_value, sender=HourRecord)       
post_delete.connect(update_po_remaining_value, sender=HourRecord) 

CalculatePOThread 线程通过获取小时记录集并从预算中扣除总小时记录集来计算剩余的 PO 预算值

hr_set = HourRecord.objects.filter(purchase_order = po)

在我的 dev.workspace 中,这工作得非常好。在生产中, post_save 连接也可以正常工作,但我遇到了 post_delete 信号的奇怪问题。查询 HourRecord.objects.filter(purchase_order = po) 返回的小时记录总和仍然包含已触发 CalculatePOThread 线程的已删除小时记录,这种情况经常发生。

无论如何,我通过在执行查询之前向线程添加 6 秒的延迟来规避该行为。时间.sleep(6)。

有人知道为什么会发生这种情况吗?似乎在记录真正从数据库中删除之前触发了 post_delete 信号..!?但这将是 Django 中的一个错误,这将是我最后的猜测。

【问题讨论】:

    标签: django multithreading django-signals


    【解决方案1】:

    很难说,但我猜你遇到了线程安全问题。当你产生一个线程来处理一个长时间运行的任务时,你必须意识到,当它试图完成时,一个类似的线程很容易被触发执行相同的任务。通常,在使用线程时,您希望尽量减少它们的占用空间,或者换句话说,不要让它们高度依赖于数据库状态等。

    如果需要访问数据库,在这种情况下,您需要设置锁以防止数据库同时被弄乱。不过,鉴于您正在运行 Django 1.1,这将变得更加困难。如何在 Django 1.1 中实现表级锁定将取决于您正在运行的数据库服务器并保证自己的问题。

    【讨论】:

    • 感谢您的回答。一个附加信息:我确保我是 prod.env 中唯一一个在搞乱的人。并一一触发 - post.delete 信号。因此,我保证没有其他线程与我的测试发生冲突。因此,锁应该由对象删除命令设置,并且 post_delete 信号只能在锁被释放/对象删除后触发。但我猜这是 Django 内部的东西,我无法影响。 PS: DB = postgres, webserver = apache.
    猜你喜欢
    • 2011-03-18
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-12
    • 1970-01-01
    相关资源
    最近更新 更多