考虑一个 Django 应用程序,它具有创建对象的单个 RESTful API(使用 Django REST Framework)。作为此 API 的一部分,我进行了一些验证以确保创建调用是幂等的,这样如果您调用创建 API 两次,第一次将成功,第二次将失败并显示自定义错误代码。
我有一个测试此 API 的场景,它会以下列方式间歇性地失败:
- 第一次 API 调用,成功,返回 201 -> 对象已经应该被创建
- 响应后立即进行第二次 API 调用
- 验证逻辑调用
MyModel.objects.get(some_field=some_value)
来检查这是否是重复调用 - 尽管在步骤 1 中创建了这样的对象,但未找到该对象,因此创建了一个重复的对象
- 检查管理/查询模型时,可以看到这两个对象。
一些更多的数据:
- 此模型上没有显式缓存,或此过程中涉及的任何其他缓存。
- 我无法在本地复制这个
- 在我的部署设置中,这种可能的竞争条件的失败率约为 5%。
- 本地和部署都使用 PostgreSQL。
- 部署环境确实启用了通用缓存,但是在本地启用缓存时仍然没有重现。
可能是什么导致了这种竞争条件? Django ORM 是否有任何故障模式,我可能会得到过时的数据?有什么方法可以防御性地保护验证免受过时数据的侵害?
最佳答案
看看 transaction.atomic:
https://docs.djangoproject.com/en/1.8/topics/db/transactions/#django.db.transaction.atomic
这有时可以解决这样的问题
关于Django ORM 返回陈旧数据,可能存在竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32661885/