【问题标题】:Django - operate on database within transaction.atomic block after raising errorDjango - 引发错误后在 transaction.atomic 块中操作数据库
【发布时间】:2018-06-12 14:18:30
【问题描述】:

我想在 transaction.atomic() 块中对我的数据库执行操作,即使在引发错误的情况下也是如此。这是一些示例代码来演示我的问题:

示例代码

# Outer try block
try:

    # Enclose in atomic transaction for database rollbacks
    with transaction.atomic():

        # If this line fails, all database updates within the outer try: block should be rolled back
        u = UU.create(email='test@test.com')

        # Inner try block
        try:
            cc = CC.objects.get(id=1)
            perform_action(cc)

        # If this exception triggers, the 'cc' object should be deleted, but all other database updates within the outer try: block should be rolled back
        except:
            cc.delete()
            raise

        # If this line fails, all database updates within the outer try: block should be rolled back
        u = UU.create(email='test@test.com')

# If any exception triggers, this error should be printed
except:
    print("Error occured.")

如果我的内部try: 块中发生错误,我希望删除cc 对象,但要回滚外部try: 块中的所有其他数据库事务。但是,就目前的代码而言,如果内部 try: 块内发生任何错误,cc.delete() 事务将被回滚。

有什么建议吗?

【问题讨论】:

    标签: django exception transactions atomic


    【解决方案1】:

    您不能只保留数据库事务的一部分,也不能在回滚外部事务的同时保留内部事务。

    相反,您可以使用自定义异常发出特定错误状态的信号,然后在回滚后捕获它时进行额外处理。比如:

    class BadCCException(Exception):
        def __init__(self, badid):
            super().__init__()
            self.badid = badid
    
    try:
        with transaction.atomic():
            u = UU.create(email='test@test.com')
    
            try:
                cc = CC.objects.get(id=1)
                perform_action(cc)
            except Exception as e:
                raise BadCCException(1) from e
    
            u = UU.create(email='test@test.com')
    except BadCCException as e:
        CC.objects.filter(id=e.badid).delete()
        print("Error occured.")
    except:
        print("Error occured.")
    

    【讨论】:

    • 太棒了——这会很好用。非常感谢您的帮助!
    猜你喜欢
    • 2017-04-07
    • 2020-11-13
    • 2014-12-09
    • 1970-01-01
    • 1970-01-01
    • 2018-09-03
    • 2014-12-04
    • 1970-01-01
    • 2016-09-14
    相关资源
    最近更新 更多