重复的请求线程在 Django 模型中创建重复的数据库条目

发布于 2024-10-21 16:51:12 字数 587 浏览 2 评论 0原文

问题:信号接收器检查特定条件下是否存在模型条目,如果不存在,则创建一个新条目。在极少数情况下,条目会被重复。

在接收器函数中:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

方圜几里 2024-10-28 16:51:13

为了防止信号重复,请将“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.

a√萤火虫的光℡ 2024-10-28 16:51:13

也许这个答案可能帮助。显然,事务可以正确地与 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 for field1, 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 a unique_together constraint on your model to further aide in integrity.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文