Django创建重复的关注关系 - 在表中创建新数据时可疑的并发问题

时间:2012-02-02 20:39:28

标签: python mysql django concurrency

让我解释一下我的具体情况:

企业可以选择他们所在的社区,此选项会持久保存到数据库,保存此对象时会触发信号。方法侦听此信号,并且只应更新跟随此邻域的所有其他用户。在此方法中进行检查,尝试验证是否有任何其他用户已经关注此业务,对于未遵循此业务的每个用户,但是在此邻域之后,将在db中创建跟随关系。一切都应该没问题,如果用户已经关注此业务,那么就没有设置关系......

但发生的事情是,有时两个或更多这些交易同时发生,当然,所有这些交易都会检查用户是否关注此业务,因为他们都没有看到用户和现在,企业建立了多个关系。

我尝试确保多次发送信号,但我不确定为什么这些多次交易同时发生。

虽然我在尝试避免更新时发生并发问题时找到了一些行锁定的答案,但我对如何确保只发生一次插入感到茫然。

表锁定是确保一种插入发生的唯一方法吗?

# when a business updates their neighborhood, this sets the follow relationship

def follow_biz(sender, instance, created, **kwargs):

    if instance.neighborhood:
        neighborhood_followers = FollowNeighborhood.objects.filter(neighborhood=instance.neighborhood)
        # print 'INSTANCE Neighborhood %s ' % instance.neighborhood
        for follower in neighborhood_followers:

            if not Follow.objects.filter(user=follower.user, business=instance).count():
                follow = Follow(business=instance, user=follower.user)
                follow.save()

# a unique static string to prevent signal from being called twice
follow_biz_signal_uid = hashlib.sha224("follow_biz").hexdigest()

# signal
post_save.connect(follow_biz, sender=Business, dispatch_uid=follow_biz_signal_uid)

1 个答案:

答案 0 :(得分:0)

通过使用相关列Django,AFAICT上的约束来确保数据库级别的行的唯一性[1],它将做正确的事情并根据需要插入或更新。

在这种情况下,约束应该是用户和业务ID。

[1]当然,在适用的情况下确保唯一性总是一个好主意。