Django - 在引发错误后在 transaction.atomic block 内对数据库进行操作

标签 django exception transactions atomic

我想在 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: 内的所有其他数据库事务要回滚的块。但是,按照现在的代码,cc.delete()如果内部 try: 内发生任何错误,事务将被回滚堵塞。

有什么建议?

最佳答案

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

相反,您可以使用自定义异常发出特定错误状态的信号,然后在回滚后捕获它时执行其他处理。就像是:

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.")

关于Django - 在引发错误后在 transaction.atomic block 内对数据库进行操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48068373/

相关文章:

c# - C#中如何通过多层代码使用事务

django - 测试电子邮件发送(即使没有设置和垃圾邮件也能测试通过)

Java - 生成自定义运行时错误而不转储跟踪

c++ - 我如何处理无效的异常处理例程?

SQL:在 REPEATABLE READ 隔离级别下,UPDATE 锁是否保持到事务结束?

java - Spring Hibernate 事务开销

python - 创建django权限,报错: ContentType matching query does not exist

django - 使用强制身份验证 Django Rest Framework 进行单元测试

python - django IntegerField 和 SmallIntegerFields 映射到 Oracle 上的相同数据库类型

c++ - 如果数组中传递的项已存在,则抛出数据异常