首页 > 解决方案 > 我应该如何使用 Django 设置的 ATOMIC_REQUESTS?它不像我预期的那样工作

问题描述

macOS、Django 1.11、mysql 5.7、

我想知道它是如何ATOMIC_REQUESTS工作的,我该如何使用它。

# some code in settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '127.0.0.1',
        'NAME': 'kma_dev',
        'USER': 'root',
        'PASSWORD': 'root',
        'ATOMIC_REQUEST': True,
    }
}

当我在视图中引发错误时,mysql 操作没有回滚。

# test raise Error in view like this⬇️⬇️


class StoreGroup(View):

    def get(self, request):
        s = Store.objects.first()
        s.name = s.name + 'ABC'
        s.save()
        raise ValueError

非常感谢。

标签: pythonmysqldjangosettings

解决方案


首先,我想您需要很好地学习 Savepoints,如docs中所述。

应用您的更改的原因是 s.save() 在引发异常之前实施。通过 s.save() 您添加一个保存点,并通过 Django 在原子事务中的默认行为(您可以阅读django.db.transaction.Atomic的代码,特别是def __exit__(self):部分)它提交事务中存在的最后一个保存点。

您可以在文档中找到更多详细信息和示例,例如如何回滚到特定保存点以及有关保存点、回滚和提交的更多详细信息。

关于 ATOMIC_REQUESTS 的说明:

Django 的默认行为是将 ATOMIC_REQUESTS 设置为 False。通过将 ATOMIC_REQUESTS 设置为 True,您将添加以下更改。通过文档:

它是这样工作的。在调用视图函数之前,Django 会启动一个事务。如果生成的响应没有问题,则 Django 提交事务。如果视图产生异常,Django 会回滚事务。

这意味着您将像这样更改默认行为,并且 Django 会警告您:

虽然这种交易模型的简单性很有吸引力,但它也会在流量增加时变得低效。为每个视图打开一个事务有一些开销。对性能的影响取决于应用程序的查询模式以及数据库处理锁定的能力。

它会警告您谨慎使用此选项,因为通过设置此选项,您的每个视图调用都将在一个事务中,并且您仍然应该注意性能(例如关心表和行锁,关心外部 api 调用)和实现(例如此链接)您将面临的困难。

顺便说一句,您可以通过@transaction.atomic装饰器或使用with transaction.atomic():语句的某些代码行将此功能添加到视图或函数中。这使您可以在需要时使用原子事务。

我强烈建议您阅读本节


推荐阅读