ATOMIC_REQUEST and Transactions in Django 1.6(Django 1.6 中的 ATOMIC_REQUEST 和事务)

本文介绍了Django 1.6 中的 ATOMIC_REQUEST 和事务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定以下代码:

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 错误是吗?让我们假设这不是我们想要的,因为我们想要优雅地处理错误,但仍然获得回滚功能.

From my understanding of transactions in Django 1.6 if do_stuff throws an exception, say an IntegrityError, then the transaction will be rolled back right. But since Django itself is calling the view nothing will stop the IntegrityError from rising up the call stack and causing an HTTP 500 error yes? Let's assume that's not what we want, as we want to gracefully handle the error, but still get the rollback functionality.

所以我想明显的想法是好的,不要那样做,使用 transaction.atomic 作为上下文管理器,它被包装在一个 try except 块中,就像这里的例子:

So I guess the obvious thought is well, don't do that, use transaction.atomic as a context manager that is wrapped in a try except block like the example here:

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

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

Fine. But then if you want to use the Transaction per HTTP Request functionality by setting ATOMIC_REQUEST = True in your db config, which means django will in effect just add the transaction.atomic decorate to your view, which won't catch any exceptions. How is ATOMIC_REQUEST even useful? Why would you ever want to let your Database errors propagate all the way up to the user?

所以我的问题是.

  1. 我在这里遗漏了什么或者我的理解是否正确?
  2. 如果我是对的,使用 ATOMIC_REQUEST 的用例是什么?我应该编写 urls.hadler500 还是应该实现一些中间件来捕获错误?
  1. What am I missing here or is my understanding correct?
  2. If I'm correct what is a use case for using ATOMIC_REQUEST? Am I expected to write a urls.hadler500 or should I implement some middleware to catch the errors?

推荐答案

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

Your understanding is correct. What you're missing is that letting exceptions propagate from your view code (which is quite different from "propagate all the way up to the user") is a perfectly normal thing to do in Django.

您可以通过制作 500.html 模板,通过覆盖 handler500,或者通过制作您自己的自定义中间件.在所有这些标准情况下,使用 ATOMIC_REQUESTS 会做你想做的事.

You can customize the resulting behavior by making a 500.html template, by overriding handler500, or by making your own custom middleware. In all of those standard cases, using ATOMIC_REQUESTS will do what you want it to do.

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

If you want to catch exceptions in your view code and handle them specially, you can certainly do that, you'll just have to specify how to handle transactions manually. Using ATOMIC_REQUESTS is just a way to save some boilerplate for the common case, while allowing you to customize the behavior yourself in the uncommon case.

这篇关于Django 1.6 中的 ATOMIC_REQUEST 和事务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!