Django Unable to rollback with try-exception block for atomic transactions

别说谁变了你拦得住时间么 提交于 2020-03-23 08:00:20

问题


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.

It looks something like this:

@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)}) 

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

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


回答1:


As suggested in the link:

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

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


来源:https://stackoverflow.com/questions/60314464/django-unable-to-rollback-with-try-exception-block-for-atomic-transactions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!