【发布时间】:2017-07-24 00:48:17
【问题描述】:
Django 的文档对transaction.atomic() 和异常有这样的说法:
https://docs.djangoproject.com/en/1.10/topics/db/transactions/#django.db.transaction.atomic
避免在 atomic 中捕获异常!
退出原子块时,Django 会查看它是正常退出还是异常退出,以确定是提交还是回滚。如果您在原子块内捕获并处理异常,您可能会向 Django 隐藏发生问题的事实。这可能会导致意外行为。
这主要是对 DatabaseError 及其子类(例如 IntegrityError)的关注。在这样的错误之后,事务被破坏,Django 将在原子块的末尾执行回滚。如果您尝试在回滚发生之前运行数据库查询,Django 将引发 TransactionManagementError。当 ORM 相关的信号处理程序引发异常时,您也可能会遇到此行为。
捕获数据库错误的正确方法是围绕原子块,如上所示。如有必要,为此添加一个额外的原子块。这种模式还有另一个优点:它明确界定了发生异常时将回滚的操作。
如果您捕获原始 SQL 查询引发的异常,则 Django 的行为是未指定的并且依赖于数据库。
这样做可以吗?或者这会导致“意外行为”吗?
with transaction.atomic():
# something
try:
# something
except:
logger.exception("Report error here.")
raise
【问题讨论】:
标签: python django transactions django-orm