尽管使用transaction.atomic,Django1.6仍然出现IntegrityError?
在 transaction.atomic()
这个块里,我正在删除并重新创建一些对象。Django 是在一个有三个工作进程的 gunicorn 后面运行,数据库使用的是 postgres。
问题:当同时有很多请求涌向服务器时,Django 会抛出一些 完整性错误:
IntegrityError: duplicate key value violates unique constraint "atomic_atomictest_name_key"
DETAIL: Key (name)=(foo) already exists.
举个例子:
models.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')
根据我的理解,这些 完整性错误 不应该出现。有人能解释一下为什么吗?
1 个回答
3
IntegrityError
错误在使用 transaction.atomic()
时仍然可能发生。这是因为多个操作可以同时进行,它们在提交之前是相互隔离的,提交后就由 Postgres 数据库来处理这些变化。如果 Postgres 发现有一个或多个操作试图创建一个违反唯一性约束的记录,它就会撤销这些操作。
transaction.atomic()
的作用是确保在这个代码块中的所有命令,如果有任何一个失败了,整个块里的所有命令都会被撤销。这样就不会出现 delete()
成功并提交了,但 save()
却失败的情况。
在这种情况下,transaction.atomic()
可能反而会导致你的问题,因为它会延迟 delete()
的立即生效。