重复的请求线程在 Django 模型中创建重复的数据库条目
问题:信号接收器检查特定条件下是否存在模型条目,如果不存在,则创建一个新条目。在极少数情况下,条目会被重复。
在接收器函数中:
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。
The problem: a signal receiver checks to see if a model entry exists for certain conditions, and if not, it creates a new entry. In some rare circumstances, the entry is being duplicated.
Within the receiver function:
try:
my_instance = MyModel.objects.get(field1=value1, field2=sender)
except:
my_instance = MyModel(field1=value1, field2=sender)
my_instance.save()
It's an obvious candidate for get_or_create
, but aside from cleaning up that code, would using get_or_create
help prevent this problem?
The signal is sent after a user action, but I don't believe that the originating request is being duplicated because that would have trigged other actions.
The duplication has occurred a few times in thousands of instances. Is this necessarily caused by multiple requests or is there some way a duplicate thread could be created? And is there a way - perhaps with granular transaction management - to prevent the duplication?
Using Django 1.1, Python 2.4, PostgreSQL 8.1, and mod_wsgi on Apache2.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为了防止信号重复,请将“dispatch_uid”参数添加到信号附件代码中,如下所示
确保您打开了一个事务 - 否则可能会发生在检查 (objects.get()) 和 cration (save()) 表状态之间发生变化的情况。
to prevent signals duplication add a "dispatch_uid" parameter to the signal attachment code as described in the docs.
make sure that you have a transaction opened - otherwise it may happen, that between checking (objects.get()) and cration (save()) state of the table changes.
也许这个答案可能帮助。显然,事务可以正确地与 get_or_create 一起使用,但我还没有确认这一点。 mod_wsgi 是多进程和多线程的(均可配置),这意味着竞争条件肯定会发生。我猜您的应用程序中发生的情况是,启动了两个单独的请求,这将为
field1
生成相同的值,并且恰好它们以正确的时机执行以添加“重复”条目。如果
MyModel(field1=value1, field2=sender)
的组合必须是唯一的,则在模型上定义unique_together
约束以进一步提高完整性。Perhaps this answer may help. Apparently, a transaction is properly used with
get_or_create
but I've not confirmed this. mod_wsgi is multi-process and multi-threaded (both configurable), which means that race conditions can definitely occur. What I guess is happening in your application is that two separate requests are launched that will generate the same value forfield1
, and it just so happens that they execute with just the right timing to add 'duplicate' entries.If the combination of
MyModel(field1=value1, field2=sender)
must be unique, then define aunique_together
constraint on your model to further aide in integrity.