Django 并发 get_or_create

McA*_*bra 3 python mysql django transactions atomicity

我担心一件事。
使用 Django 1.7(大多数默认安装中的 MySQL)我正在向 Django REST Framework 发送 POST APIView。那边我在做:

try:
    MyModel.objects.get(**some_kwargs)
except MyModel.DoesNotExist:
    MyModel.objects.custom_create(**some_kwargs)  # This also creates relative models
Run Code Online (Sandbox Code Playgroud)

现在,如果我要执行大量并发请求,会发生什么?
正如我猜你所期望的,我只想要第一个并发请求来创建一个对象,其他任何请求都应该得到创建的对象。

感谢 Django,我准备好了吗?必须研究隔离、事务、原子性?或者更多的是关于锁定桌子?如何(单元)测试它?

请指导我。

knb*_*nbk 7

这不足以避免竞争条件,因为另一个请求可以创建您打算在get()和之间检索的模型custom_create()。如果在数据库级别强制执行唯一性,则您的custom_create()方法可能会失败并显示IntegrityError. 如果不是,则您的方法很好,但是由于竞争条件,您无法防止重复条目。

Django 提供了该get_or_create()功能。如果您的数据库强制执行唯一性,这可以防止竞争条件。create()但是,它使用该方法,而不是您的custom_create()方法,因此如果可以接受,您必须覆盖它。否则,您可以签出源代码get_or_create(),并与您创建自定义的方法实现它自己。

的核心假设get_or_create是在数据库级别强制执行唯一性。由于这种强制,create如果发生竞争条件,则失败,并且get_or_create可以回退到获取在竞争条件期间创建的对象。如果缺少此强制执行,则create在竞争条件期间不会失败,并且将创建重复条目(具有不同的 PK)。