django get_or_create()不是线程安全的

最近数据库出现了莫名的BUG,一条记录会同时创建两次。

为了解决这个问题,首先看了一下代码,代码用了get_or_create()这个方法,翻看了源码:

    def get_or_create(self, defaults=None, **kwargs):
        """
        Look up an object with the given kwargs, creating one if necessary.
        Return a tuple of (object, created), where created is a boolean
        specifying whether an object was created.
        """
        lookup, params = self._extract_model_params(defaults, **kwargs)
        # The get() needs to be targeted at the write database in order
        # to avoid potential transaction consistency problems.
        self._for_write = True
        try:
            return self.get(**lookup), False
        except self.model.DoesNotExist:
            return self._create_object_from_params(lookup, params)

原来这个方法不是原子的,如果并发操作会出现问题(就像我的创建了两次)。不过这个方法的名字太“原子”了,会让人误以为是线程安全的,如果改成get_or_create_unsafely()可能会让人谨慎起来。

接着,我查看了一下日志,果真是有并发的请求,难怪会出现这样的问题。

解决方案:

  1. 配合事务一起使用
  2. 在model层加限制uniqueunique_together

大家如果喜欢,欢迎点赞分享评论哦!😘

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,614评论 1 32
  • ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。 O...
    我想起个好名字阅读 5,900评论 0 9
  • 原文:https://my.oschina.net/liuyuantao/blog/751438 查询集API 参...
    阳光小镇少爷阅读 3,951评论 0 8
  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 32,266评论 2 89
  • 一天的下午,腿脚不利索的体型偏胖的姑娘和她妈妈来到店面,看见她腿脚不利索,其他人也不想接她,但是我的下意识告诉...
    wh王辉阅读 568评论 1 0

友情链接更多精彩内容