尽管使用transaction.atomic,Django1.6仍然出现IntegrityError?

3 投票
1 回答
1235 浏览
提问于 2025-04-18 11:50

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() 的立即生效。

撰写回答