Django 事务:在 save() 方法的重写中以原子方式管理两个不同的事务

Django transactions: managing two different transactions atomically inside the overriding of save() method

在 Django 1.4 中,我有如下代码:

from django.db import models
from django.db import transaction

class MyModel(models.Model):
    # model definition

    @transaction.commit_manually
    def save(self, *args, **kwargs):
        try:
            super(MyModel, self).save(*args, **kwargs)
            do_other_things()
        except:
            transaction.rollback()
            raise
        else:
            transaction.commit()
            obj2 = MySecondModel(mymodel = self, foo = "bar")
            obj2.save()


class MySecondModel(models.Model):
    myModelId = models.ForeignKey(MyModel)
    # other fields defining this model

如您所见,在创建 MyModel class 的对象后,我还必须创建另一个 MySecondModel class 的对象,该对象引用了第一个。

在上面的代码中,如果 obj2.save() 期间出现问题,将无法回滚第一个事务。

如何将这两个交易作为一个唯一的原子交易来处理?

正如 Gocht 在问题下的评论中所建议的,Django 1.4 中的解决方案是使用 @transaction.commit_on_success()。代码可能是这样的:

from django.db import models
from django.db import transaction

class MyModel(models.Model):
    # model definition

    @transaction.commit_on_success()
    def save(self, *args, **kwargs):
        try:
            super(MyModel, self).save(*args, **kwargs)
            do_other_things()
            obj2 = MySecondModel(mymodel = self, foo = "bar")
            obj2.save()
        except:
            print 'exception'
            raise
        else:
            print 'job done'



class MySecondModel(models.Model):
    myModelId = models.ForeignKey(MyModel)
    # other fields defining this model