Django 嵌套 Transaction.atomic 未回滚
Django nested Transaction.atomic not rolled back
我在两个不同的数据库中有两个逻辑连接的实例。我希望它们都被保存或回滚。但是,如果我在外部块中引发异常 - 嵌套 Transaction.atomic
将不会回滚,但为什么呢?
来自文档:
atomic blocks can be nested. In this case, when an inner block
completes successfully, its effects can still be rolled back if an
exception is raised in the outer block at a later point.
def __commit_to_db(self, mesure, mdm_mesure):
try:
with transaction.atomic():
mesure.save()
with transaction.atomic(using='mdm'):
mdm_mesure.save()
raise Exception('oops')
except (KeyboardInterrupt, SystemExit):
raise
except BaseException as error:
MainLoger.log_error(error)
return
事务是数据库级别的功能。因此,尽管您嵌套了 Python 代码,但每个数据库实际上都在独立于其他数据库获取自己的事务。 Django 中没有跨数据库的嵌套事务。
您必须以某种方式重构您的代码。例如,将您的代码放在两个 atomic()
块中会起作用:
try:
with transaction.atomic():
with transaction.atomic(using='mdm'):
mesure.save()
mdm_mesure.save()
# neither transaction will commit
raise Exception('oops')
except Exception:
pass
我在两个不同的数据库中有两个逻辑连接的实例。我希望它们都被保存或回滚。但是,如果我在外部块中引发异常 - 嵌套 Transaction.atomic
将不会回滚,但为什么呢?
来自文档:
atomic blocks can be nested. In this case, when an inner block completes successfully, its effects can still be rolled back if an exception is raised in the outer block at a later point.
def __commit_to_db(self, mesure, mdm_mesure):
try:
with transaction.atomic():
mesure.save()
with transaction.atomic(using='mdm'):
mdm_mesure.save()
raise Exception('oops')
except (KeyboardInterrupt, SystemExit):
raise
except BaseException as error:
MainLoger.log_error(error)
return
事务是数据库级别的功能。因此,尽管您嵌套了 Python 代码,但每个数据库实际上都在独立于其他数据库获取自己的事务。 Django 中没有跨数据库的嵌套事务。
您必须以某种方式重构您的代码。例如,将您的代码放在两个 atomic()
块中会起作用:
try:
with transaction.atomic():
with transaction.atomic(using='mdm'):
mesure.save()
mdm_mesure.save()
# neither transaction will commit
raise Exception('oops')
except Exception:
pass