0

我有一个模型(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 中的一个错误,这将是我最后的猜测。

4

1 回答 1

1

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

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

于 2012-05-07T20:24:14.537 回答