原子块可以嵌套。在这种情况下,当内部块 成功完成,如果 稍后会在外部块中引发异常。
我是否正确理解我不需要在do_stuff()
之前添加@transaction.atomic
装饰器?如果do_staff更改数据库并发生异常,则父view_func
将负责回滚。
from django.db import transaction
@transaction.atomic
def viewfunc(request):
# This code executes inside a transaction.
do_stuff()
这不是必需的,对吗?
from django.db import transaction
@transaction.atomic
def do_stuff():
do_something_in_the_database()
@transaction.atomic
def viewfunc(request):
# This code executes inside a transaction.
do_stuff()
这取决于您要做什么。 您显示代码的方式 - 不,您不需要do_stuff
@transaction.atomic
.
但是,如果您希望do_stuff
能够独立于viewfunc
而失败,您可能会这样做。
例如:
@transaction.atomic
def viewfunc(request):
try:
do_stuff()
except Exception:
handle_exception()
do_other_stuff
在这种情况下,do_stuff
失败将回滚该段,但不会取消外部事务。
您可以在此处查看更多详细信息:https://docs.djangoproject.com/en/2.2/topics/db/transactions/
您使用的引号说,如果引发异常,则viewfunc
都会发生回滚,无论嵌套原子在do_stuff
中是否成功。
但是,是的,您的假设是正确的,即如果do_stuff
或viewfunc
引发异常,viewfunc
上的原子将负责回滚。
我仍然会装饰do_stuff
以便您可以在viewfunc
中处理它引发的异常,同时回滚事务。如果仅修饰viewfunc
则错误可能会传播并最终向用户显示 500 个错误的视图。