gpt4 book ai didi

django - TransactionManagementError 隐藏根异常

转载 作者:行者123 更新时间:2023-12-03 10:44:32 27 4
gpt4 key购买 nike

当代码在 transaction.atomic 块中执行并引发异常时,数据库处理程序被标记为需要回滚。如果仍然在该 transaction.atomic 块中执行后续查询,则会引发以下错误:

TransactionManagementError: An error occurred in the current transaction. You can't execute queries until the end of the 'atomic'



在这一点上,实际的根错误被掩盖并且很难访问,让您需要跳入 Django 的事务代码。

一个可能导致此错误的简单示例:
def someview(request):
with transaction.atomic():
// do some things
instance = SomeModel.objects.create(...)
// some other db queries

@receiver(post_save, sender=SomeModel)
def non_critical_side_effect(
sender, instance, created, raw, using, update_fields, **kwargs
):
try:
// some query that causes a database error
SomeModelLog.objects.create(some_non_none_field=None)
except IntegrityError:
//notify ourselves, go on
pass

当您遇到这种情况时,您如何弄清楚真正发生了什么,以及您如何定期避免这种情况?

(下面的自我回答 - 但真正对其他人的想法感兴趣!)

最佳答案

如果您使用的是 django.db.transaction.atomic上下文管理器并被 TransactionManagementError 难倒,您可以通过检查 exc_value 的值来确定根本原因。当needs_rollback设置为 Truedjango.db.transaction.Atomic.__exit__ .这应该是提示需要回滚事务的异常。

为了首先避免这个错误,我采用了两种方法:

  • 避免在 transaction.atomic 中包装大块代码
  • 如果您确实需要更大的 transaction.atomic块,确保该块中任何可能失败而不需要回滚整个事务的部分都包含在它们自己的子事务中。

  • 我的原始示例更正后,即使信号处理程序遇到数据库错误, View 仍可以继续执行:
    def someview(request):
    with transaction.atomic():
    // do some things
    SomeModel.objects.create(invalid_field=123)

    @receiver(post_save, sender=SomeModel)
    def non_critical_side_effect(
    sender, instance, created, raw, using, update_fields, **kwargs
    ):
    try:
    with transaction.atomic():
    // some query that causes a database error
    except IntegrityError:
    // notify ourselves, go on
    pass

    关于django - TransactionManagementError 隐藏根异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45890610/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com