Django 1.6中的ATOMIC_REQUEST和事务

j1z*_*1z0 7 python django transactions

给出以下代码:

from django.db import transaction

@transaction.atomic
def viewfunc(request):
    # This code executes inside a transaction.
    do_stuff()
Run Code Online (Sandbox Code Playgroud)

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

所以我想明显的想法是好的,不要这样做,transaction.atomic用作包含在try中的上下文管理器,除了像这里的例子一样的块:

try:
    with transaction.atomic():
        generate_relationships()
except IntegrityError:
    handle_exception()
Run Code Online (Sandbox Code Playgroud)

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

所以我的问题是.

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

Kev*_*nry 4

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

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

如果您想捕获视图代码中的异常并专门处理它们,您当然可以这样做,您只需指定如何手动处理事务即可。使用ATOMIC_REQUESTS只是为常见情况保存一些样板文件的一种方法,同时允许您在不常见情况下自行自定义行为。