问题:信号接收器检查某些条件是否存在模型条目,如果不存在,则会创建一个新条目。在一些罕见的情况下,该条目正在重复。
在接收函数中:
try:
my_instance = MyModel.objects.get(field1=value1, field2=sender)
except:
my_instance = MyModel(field1=value1, field2=sender)
my_instance.save()
这是get_or_create
的明显候选人,但除了清理该代码外,使用get_or_create
有助于防止此问题吗?
信号是在用户操作后发送的,但我不认为原始请求是重复的,因为这会触发其他操作。
在数千个实例中发生了几次重复。这是否必然是由多个请求引起的,或者是否有某种方式可以创建重复的线程?有没有办法 - 可能采用粒度事务管理 - 来防止重复?
在Apache2上使用Django 1.1,Python 2.4,PostgreSQL 8.1和mod_wsgi。
答案 0 :(得分:2)
为防止信号重复,将“dispatch_uid”参数添加到信号附件代码described in the docs。
确保您已打开一个事务 - 否则可能会发生,检查(objects.get())和cration(save())表之间的状态发生变化。
答案 1 :(得分:1)
也许this answer可能会有所帮助。显然,交易与get_or_create
正确使用,但我没有证实这一点。 mod_wsgi是多进程和多线程(都是可配置的),这意味着肯定会出现竞争条件。我猜你的应用程序中发生了两个单独的请求,这些请求将为field1
生成相同的值,并且它恰好在恰当的时间执行以添加“重复”条目。
如果MyModel(field1=value1, field2=sender)
的组合必须是唯一的,那么请在模型上定义unique_together
约束,以进一步提升完整性。