Django并发get_or_create

时间:2015-04-04 12:27:20

标签: python mysql django transactions atomicity

我关心一件事。
使用Django 1.7(MySQL在最默认的安装中)我正在对Django REST框架APIView进行POST。 那边我做了一个:

try:
    MyModel.objects.get(**some_kwargs)
except MyModel.DoesNotExist:
    MyModel.objects.custom_create(**some_kwargs)  # This also creates relative models

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

我准备好了,感谢Django吗?必须研究隔离,交易,原子性?还是更多关于锁定桌子?如何(单位)测试它?

请指导我。

1 个答案:

答案 0 :(得分:3)

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

Django提供get_or_create()功能。如果您的数据库强制执行唯一性,则可以防止竞争条件。它使用create()方法,而不是custom_create()方法,因此如果可以接受,则必须覆盖它。否则,您可以查看get_or_create()的{​​{3}}并使用自定义创建方法自行实施。

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