Django 1.6中的ATOMIC_REQUEST和事务 [英] ATOMIC_REQUEST and Transactions in Django 1.6

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

问题描述

鉴于以下代码:

  from django.db import transaction 

@ transaction.atomic
def viewfunc(request):
#此代码在事务中执行。
do_stuff()

从我对Django 1.6中的事务的理解,如果do_stuff引发异常,说一个IntegrityError,那么事务将被回滚。但是,由于Django本身正在调用该视图,所以没有什么会阻止IntegrityError上升调用堆栈并导致HTTP 500错误是?让我们假设这不是我们想要的,因为我们想要优雅地处理错误,但仍然得到回滚功能。



所以我猜这个明显的想法很好,这样做,使用 transaction.atomic 作为包装在一个尝试中的外部管理器,除了块,如下例所示:



$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $

很好。但是,如果要在数据库配置中设置ATOMIC_REQUEST = True来使用HTTP请求功能,这意味着django实际上只需将 transaction.atomic decorate添加到你的观点,这不会有任何例外。 ATOMIC_REQUEST如何有用?你为什么要让数据库错误一直传播给用户?



所以我的问题是。


  1. 我在这里遇到什么或者我的理解正确吗?

  2. 如果我使用ATOMIC_REQUEST有什么用例,我希望写一个 urls.hadler500 ,还是应该实现一些中间件来捕捉错误?


解决方案

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



您可以通过使 500.html模板,覆盖 handler500 ,或者制作自己的自定义中间件。在所有这些标准案例中,使用 ATOMIC_REQUESTS 将执行您想要的操作。



如果您要在视图代码中捕获异常并特别处理它们,您当然可以这样做,您只需要手动指定如何处理事务。使用 ATOMIC_REQUESTS 只是为了保护常见的案例的一些方法,同时允许您在不常见的情况下自行定制行为。


Given the following code:

from django.db import transaction

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

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.

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()

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?

So my question is.

  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?

解决方案

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.

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.

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和事务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆