一尘不染

Django 1.6中的ATOMIC_REQUEST和事务

python

给出以下代码:

from django.db import transaction

@transaction.atomic
def viewfunc(request):
    # This code executes inside a transaction.
    do_stuff()

根据我对Django
1.6中事务的理解,如果do_stuff抛出异常(例如IntegrityError),那么事务将被正确回滚。但是由于Django本身正在调用视图,所以没有什么可以阻止IntegrityError上升调用堆栈并导致HTTP
500错误的吗?让我们假设这不是我们想要的,因为我们想要优雅地处理错误,但仍然可以获得回滚功能。

因此,我想显而易见的想法是好的,不要那样做,将其transaction.atomic用作上下文管理器,该上下文管理器包含在try
try块中,例如此处的示例:

try:
    with transaction.atomic():
        generate_relationships()
except IntegrityError:
    handle_exception()

精细。但是,如果您想通过在数据库配置中设置ATOMIC_REQUEST =
True来使用“每个HTTP请求的事务”功能,这意味着django实际上只会将transaction.atomic装饰添加到视图中,而不会捕获任何异常。ATOMIC_REQUEST甚至有什么用?为什么要让您的数据库错误一直传播到用户?

所以我的问题是。

  1. 我在这里缺少什么,或者我的理解正确吗?
  2. 如果我是正确的,那么使用ATOMIC_REQUEST的用例是什么?我应该编写一个urls.hadler500还是应该实现一些中间件来捕获错误?

阅读 269

收藏
2021-01-20

共1个答案

一尘不染

您的理解是正确的。您所缺少的是,让异常从您的视图代码传播(这与“一直传播到用户”大不相同)在Django中是完全正常的事情。

您可以通过创建500.html模板,覆盖handler500或制作自己的自定义中间件来自定义结果行为。在所有这些标准情况下,使用ATOMIC_REQUESTS都会做您想要做的事情。

如果您想在视图代码中捕获异常并进行特​​殊处理,则可以做到这一点,您只需要指定如何手动处理事务即可。使用ATOMIC_REQUESTS只是为常见情况节省一些样板的一种方法,同时允许您在罕见情况下自己定制行为。

2021-01-20