在 transaction.atomic() 中,我正在删除并重新创建对象。 Django 坐在一个 3-worker gunicorn 后面,数据库是 postgres。
问题:当同时向服务器发送大量请求时,Django 会抛出一些 IntegrityErrors:
IntegrityError: duplicate key value violates unique constraint "atomic_atomictest_name_key"
DETAIL: Key (name)=(foo) already exists.
例子:
模型.py
class AtomicTest(models.Model):
name = models.TextField(null=False, unique=True)
views.py
def test_atomic(request):
with transaction.atomic():
models.AtomicTest.objects.filter(name='foo').delete()
models.AtomicTest(name='foo').save()
return http.HttpResponse('OK')
IntegrityErrors 在我看来不应该发生。谁能解释一下为什么?
请您参考如下方法:
IntegrityError 仍然会在 transaction.atomic() 中发生。交易可以同时发生;他们只是在提交之前彼此隔离,此时由 Postgres 尝试协调更改。如果 Postgres 确定一个或多个事务试图创建违反唯一性约束的行,它将回滚这些事务。
transaction.atomic() 所做的是确保 block 中的所有命令在其中任何命令失败时回滚。这样您就不会遇到 delete() 成功并提交但 save() 失败的情况。
在这种情况下,transaction.atomic() 可能实际上导致了您的问题,因为它延迟了 delete() 立即生效。
