我有一个模型(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秒的延迟来规避行为。 time.sleep(6)。
有人知道为什么会出现这种情况吗?似乎在从数据库中删除记录之前触发了post_delete信号..!?但这将是Django中的一个错误,这将是我的最后一次猜测。
答案 0 :(得分:1)
很难说,但我的猜测是你遇到了线程安全问题。当你产生一个线程来处理一个长时间运行的任务时,你必须意识到,当它试图完成时,一个类似的线程可以很容易地被解雇。通常,在使用线程时,您希望保持最小的占用空间,换句话说,不要让它们高度依赖于数据库状态等。
如果数据库访问 是必需的,在这种情况下,您需要设置锁以防止数据库同时搞乱。考虑到你正在运行Django 1.1,这将变得更加困难。如何在Django 1.1中实现表级锁定将依赖于您正在运行的数据库服务器并保证自己的问题。