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
在 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