python - Django无法使用原子事务的try-exception块回滚
问题描述
我在 Django 中的一个视图对 6-7 个表执行保存操作。我希望这些事务是原子的,例如,如果第 5 或第 6 个事务失败,我想回滚所有以前的保存。该视图包含一个 try-except 块来处理引发的异常。
它看起来像这样:
@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 回滚没有发生。我想{"Status": 0, Data: "Error That occurred"}
在所有情况下都返回 JSON 响应。我不想像在此链接中所做的那样在 except 块中重新引发异常
如果失败,我应该怎么做才能返回正确的 JSONResponse 并回滚所有内容?
解决方案
正如链接中所建议的:
如果您的视图产生没有错误的响应,transaction.atomic将在数据库上执行事务。因为您自己捕获了异常,所以在 Django 看来,您的视图执行得很好。如果捕捉到异常,需要自己处理
另一种方法是使用transaction.atomic
inside with
(作为上下文管理器),这将确保提交或回滚(再次在同一链接上建议并在此处解释)
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)})
推荐阅读
- java - Choco-Solver Java 库是否支持并行编程?
- python - 给定一个数据框,如何根据名称对列进行分桶并将同一桶中的列合并为一个?
- freemarker - Freemarker 以毫秒为单位将时间戳转换为带有时区的日期
- python - Imapclient 附件方法
- vba - 不支持 VBA FireEvent 方法
- javascript - 在 React 父功能组件(react-dual-listbox)中访问 React 子类组件状态的最佳方法
- javascript - Sequelize - 我必须在哪里放置“onDelete”选项
- swift - 方法`enumerateChildNodes`没有找到节点
- linux-kernel - 如何在arm上使用pte页面映射强制lowmem映射?
- c# - 如果源和日志名称不同,Serilog 事件日志将不起作用