Skip to main content
 首页 » 编程设计

python之Django1.6 IntegrityError 尽管有 transaction.atomic()

2024年10月25日43langtianya

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