Django 运行 get_or_create
Django concurrent get_or_create
我担心一件事。
使用 Django 1.7(MySQL 在大多数默认安装中)我正在为 Django REST Framework APIView
创建一个 POST。
我在那边做:
try:
MyModel.objects.get(**some_kwargs)
except MyModel.DoesNotExist:
MyModel.objects.custom_create(**some_kwargs) # This also creates relative models
现在,如果我执行大量并发请求会怎样?
正如我猜你期望的那样,我只希望第一个并发请求创建一个对象,而任何其他请求都应该获得创建的对象。
我准备好了吗,谢谢 Django?非要研究隔离、事务、原子性?还是更多关于锁定 table?如何(单元)测试它?
请指导我。
这不足以避免竞争条件,因为另一个请求可以创建您打算在 get()
和 custom_create()
之间检索的模型。如果在数据库级别强制执行唯一性,您的 custom_create()
方法可能会失败并返回 IntegrityError
。如果不是,则您的方法很好,但您无法防止由于竞争条件而导致的重复条目。
Django 提供了 get_or_create()
功能。如果您的数据库强制执行唯一性,这可以防止竞争条件。但是,它使用 create()
方法,而不是您的 custom_create()
方法,因此如果可以接受,您必须覆盖它。否则,您可以签出 get_or_create()
的 source code 并使用自定义创建方法自行实现。
get_or_create
的核心假设是在数据库级别强制执行唯一性。由于这种强制执行,如果出现竞争条件,create
将失败,并且 get_or_create
可以退回到获取在竞争条件期间创建的对象。如果缺少此强制执行,则 create
在竞争条件下不会失败,并且将创建重复条目(具有不同的 PK)。
我担心一件事。
使用 Django 1.7(MySQL 在大多数默认安装中)我正在为 Django REST Framework APIView
创建一个 POST。
我在那边做:
try:
MyModel.objects.get(**some_kwargs)
except MyModel.DoesNotExist:
MyModel.objects.custom_create(**some_kwargs) # This also creates relative models
现在,如果我执行大量并发请求会怎样?
正如我猜你期望的那样,我只希望第一个并发请求创建一个对象,而任何其他请求都应该获得创建的对象。
我准备好了吗,谢谢 Django?非要研究隔离、事务、原子性?还是更多关于锁定 table?如何(单元)测试它?
请指导我。
这不足以避免竞争条件,因为另一个请求可以创建您打算在 get()
和 custom_create()
之间检索的模型。如果在数据库级别强制执行唯一性,您的 custom_create()
方法可能会失败并返回 IntegrityError
。如果不是,则您的方法很好,但您无法防止由于竞争条件而导致的重复条目。
Django 提供了 get_or_create()
功能。如果您的数据库强制执行唯一性,这可以防止竞争条件。但是,它使用 create()
方法,而不是您的 custom_create()
方法,因此如果可以接受,您必须覆盖它。否则,您可以签出 get_or_create()
的 source code 并使用自定义创建方法自行实现。
get_or_create
的核心假设是在数据库级别强制执行唯一性。由于这种强制执行,如果出现竞争条件,create
将失败,并且 get_or_create
可以退回到获取在竞争条件期间创建的对象。如果缺少此强制执行,则 create
在竞争条件下不会失败,并且将创建重复条目(具有不同的 PK)。