问题
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