当前位置:  开发笔记 > 编程语言 > 正文

Django - 使用事务原子回滚保存

如何解决《Django-使用事务原子回滚保存》经验,为你挑选了2个好方法。

我正在尝试创建一个保存对象的视图,但是如果引发一些异常,我想撤消该保存.这是我试过的:

class MyView(View):

    @transation.atomic
    def post(self, request, *args, **kwargs):
        try:
            some_object = SomeModel(...)
            some_object.save()

            if something:
                raise exception.NotAcceptable()
                # When the workflow comes into this condition, I think the previous save should be undome
                # Whant am I missing?

        except exception.NotAcceptable, e:
            # do something

我究竟做错了什么?即使引发异常some_object仍然在DataBase中.



1> jlucier..:

原子文档

总而言之,@transaction.atomic如果您的视图产生没有错误的响应,将在数据库上执行事务.因为你自己正在捕获异常,所以Django认为你的视图执行得很好.

如果您发现异常,则需要自己处理:控制事务

如果您在发生故障时需要生成适当的json响应:

from django.db import SomeError, transaction

def viewfunc(request):
    do_something()

    try:
        with transaction.atomic():
            thing_that_might_fail()
    except SomeError:
        handle_exception()

    render_response()


不,如果您想捕获异常,则必须在try..except块内使用“ with transaction.atomic”。我的观点是,您可以同时对视图使用@ transaction.atomic。如果您想使do_something()和try..except块的结果处于成功或失败的一个事务中,则这仍然有用。

2> jpic..:

但是,如果一个例外饰有transaction.atomic功能情况,那么你没有什么做的,它会自动回滚到运行在你的函数之前,由装饰创建保存点,为记录:

atomic允许我们创建一个代码块,在该代码块中保证数据库的原子性.如果代码块成功完成,则更改将提交到数据库.如果存在异常,则回滚更改.

如果在except块中捕获异常,则应该重新引发异常以捕获它并执行回滚,即:

    try:
        some_object = SomeModel(...)
        some_object.save()

        if something:
            raise exception.NotAcceptable()
            # When the workflow comes into this condition, I think the previous save should be undome
            # Whant am I missing?

    except exception.NotAcceptable, e:
        # do something
        raise  # re-raise the exception to make transaction.atomic rollback

此外,如果您想要更多控制,您可以手动回滚到先前设置的保存点,即:

class MyView(View):
    def post(self, request, *args, **kwargs):
        sid = transaction.savepoint()
        some_object = SomeModel(...)
        some_object.save()

        if something:
            transaction.savepoint_rollback(sid)
        else:
            try:
                # In worst case scenario, this might fail too
                transaction.savepoint_commit(sid)
            except IntegrityError:
                transaction.savepoint_rollback(sid)

推荐阅读
女女的家_747
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有