django - 如何避免将模型字段更新为最新时间戳时的竞争条件

标签 django postgresql django-orm race-condition

我需要跟踪帖子中提及用户的最近时间,并在每次创建新帖子时根据其发布时间更新此字段。

我当前的代码如下所示:

from django.db.models.signals import post_save
from django.dispatch import receiver
from messageboard.models import Post

@receiver(post_save, sender=Post)
def user_last_mentioned_updater(sender, instance, **kwargs):
    for users in instance.mentions:
        user.last_mentioned = max(user.last_mentioned, instance.timestamp)
        user.save()

但是,如果同时处理两个帖子,则可能会将 last_laid 字段保留为较早帖子的时间戳。

不幸的是,F不支持max操作,当我尝试它时,我得到一个TypeError: unorderable types: datetime.datetime() > F ():

user.last_mentioned = max(F('last_mentioned'), instance.timestamp)

如何避免这种竞争条件?

如果重要的话,目前我正在使用 Postgresql 作为 ORM,尽管这可能会发生变化。

最佳答案

这是一个应该没有竞争条件并且更高效的版本:

@receiver(post_save, sender=Post)
def user_last_mentioned_updater(sender, instance, **kwargs)
    User.objects.filter(
        id__in=[u.id for u in instance.mentions],
        last_mentioned__lt=instance.timestamp,
    ).update(last_mentioned=instance.timestamp)

也就是说,我们选择提到的需要更新时间戳的用户,并在单个 SQL 语句中更新它们。

关于django - 如何避免将模型字段更新为最新时间戳时的竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44189588/

相关文章:

python - 尝试通过中间表进行过滤

django - 如何获取涉及Django中多对多关系的对象列表

python - 减去两个带注释的列

python - Django - 反转自定义管理 URL

python - 从外部网站获取元描述

python - 如何在 Django Python 中从子类访问父类字段

python - 如何使用 django ORM 在 postgres 中只选择日期部分

javascript - django post请求未在终端中显示javascript blob对象

java - 为什么@NaturalId 不在数据库中创建唯一约束?

arrays - 计算 Postgres 数组中重叠元素的数量