Django无法回退带有原子事务的try-exception块 [英] Django Unable to rollback with try-exception block for atomic transactions

查看:261
本文介绍了Django无法回退带有原子事务的try-exception块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Django中的一个观点对6-7个表执行保存操作。我希望这些事务是原子性的,如果第五或第六次事务失败,我想回滚所有以前的保存。
该视图包含一个try-except块来处理引发的异常。

One of my view in Django executes save operations on 6-7 tables. I want these transactions to be atomic I,e if the 5th or 6th transaction fail I want to rollback all the previous saves. The view contains a try-except block to handle the exceptions raised.

它看起来像这样:

@transaction.atomic
def my_view(request):
    sid = transaction.savepoint()
    try:
        Table1.save()
        Table2.save()
        Table3.save()
        Table4.save()
        Table5.save()
        Table6.save()
        Table7.save()  # This might fail. In case of failure I want to rollback saves from Table1 to Table6

        transaction.savepoint_commit(sid)
    except Exception as e:
        print(str(e))
        transaction.savepoint_rollback(sid)
        return JsonResponse({"Status": 0, "Data": str(e)}) 

我尝试了上述操作,但Table7.save()失败了,并且没有发生Table1到Table6的回滚。
我想在所有情况下以 {状态:0,数据:发生错误} 的形式返回JSON响应。
我不想在此链接

I've tried the above and Table7.save() has failed and Table1 to Table6 rollback has not happened. I want to return the JSON response as {"Status": 0, Data: "Error That occurred"} in all the cases. I don't want to re-raise the exception in except block as done in This link

我应该怎么做才能返回正确的JSONResponse并在失败的情况下回滚所有内容?

What should I do to return a proper JSONResponse and rollback everything in case of failure?

推荐答案

链接中所建议:


transaction.atomic 将在数据库上执行事务。由于您自己正在捕获
异常,因此在Django中,您的视图仅执行
罚款。如果发现异常,则需要自己处理

transaction.atomic will execute a transaction on the database if your view produces a response without errors. Because you're catching the exception yourself, it appears to Django that your view executed just fine. If you catch the exception, you need to handle it yourself

另一种方法是使用 transaction.atomic 中的和(作为上下文管理器),这将确保提交或回滚(再次在同一链接上建议,并解释了此处

An alternative approach is to use transaction.atomic inside with (as context manager), which will ensure a commit or rollback (again suggested on the same link and also explained here)

def my_view(request):
    try:
        with transaction.atomic():
            Table1.save()
            Table2.save()
            Table3.save()
            Table4.save()
            Table5.save()
            Table6.save()
            Table7.save()  # This might fail. In case of failure I want to rollback saves from Table1 to Table6

    except Exception as e:
        print(str(e))
        return JsonResponse({"Status": 0, "Data": str(e)}) 

这篇关于Django无法回退带有原子事务的try-exception块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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