Python 使用嵌套的Django transaction.atomic()处理异常?

Python 使用嵌套的Django transaction.atomic()处理异常?,python,django,transactions,Python,Django,Transactions,Django的文档中提到了transaction.atomic()和异常: 避免捕获原子内部的异常 捕捉数据库错误的正确方法是围绕一个原子块,如上所示。如有必要,为此添加一个额外的原子块。此模式还有另一个优点:它明确地限定了发生异常时将回滚哪些操作 “如有必要,为此目的添加一个额外的原子块”是什么样的?我可以这样做吗?还是会导致“意外行为” 他们想这样写吗?如果是的话,为什么会有所不同 valid = True errors = [] objects = MyModel.objects.a

Django的文档中提到了
transaction.atomic()
和异常:

避免捕获原子内部的异常

捕捉数据库错误的正确方法是围绕一个原子块,如上所示。如有必要,为此添加一个额外的原子块。此模式还有另一个优点:它明确地限定了发生异常时将回滚哪些操作

“如有必要,为此目的添加一个额外的原子块”是什么样的?我可以这样做吗?还是会导致“意外行为”

他们想这样写吗?如果是的话,为什么会有所不同

valid = True
errors = []
objects = MyModel.objects.all()
try:
    with transaction.atomic():
        for obj in objects:
            try:
                with transaction.atomic():  # Here's my 'extra atomic block'
                    # Update and save obj here...
            except:
                errors.append("obj {} had errors".format(obj.pk))
                valid = False
        if not valid:
            raise Exception('batch update failed.')

except Exception as ex:
    # Handle it..

Django仅在事务块捕捉到
数据库错误
(或其子类)时触发rolback,所以您不应该在它之前捕捉它。若您添加第二个事务块(您的第二个示例),则会捕获错误,事务被标记为回滚,然后您可以执行任何您想要的操作


我认为,如果您再次提出完全相同的错误,您应该很好,但这只是一个猜测。

>在它之前捕获它?在您的第一个示例中,您在事务块结束之前捕获错误,因此事务逻辑不知道出了什么问题,也不会回滚事务。我希望现在能更容易理解。更清楚的是,如果事务块异常退出,Django会触发回滚。但是,
DatabaseError
表示当前事务存在问题,因此在回滚引发它的(最里面的)原子块之前,您不应该捕获
DatabaseError
。对于其他异常,如果不希望回滚事务,可以在原子块内捕获它们。
valid = True
errors = []
objects = MyModel.objects.all()
try:
    with transaction.atomic():
        for obj in objects:
            try:
                with transaction.atomic():  # Here's my 'extra atomic block'
                    # Update and save obj here...
            except:
                errors.append("obj {} had errors".format(obj.pk))
                valid = False
        if not valid:
            raise Exception('batch update failed.')

except Exception as ex:
    # Handle it..