【发布时间】:2010-07-04 12:44:14
【问题描述】:
我有以下代码覆盖模型的保存方法:
@transaction.commit_on_success
def save(self, *args, **kwargs):
try:
transaction.commit()
self.qa.vote_down_count += 1
self.qa.save()
super(self.__class__, self).save(*args, **kwargs)
except:
transaction.rollback()
raise
else:
transaction.commit()
预期的行为是:self.qa 属性 vote_down_count 加一,但如果在 super(self) 保存方法中发生任何异常,事务将回滚(这意味着 self.qa.vote_down_count += 1 未提交在数据库中)。
实际行为是:self.qa.vote_down_count += 1 已提交到数据库,即使从 super(self) 保存引发 IntegrityError 异常。
有什么想法吗?
【问题讨论】:
-
你为什么先提交,最后再提交?
-
提交第一件事会打开事务并确保提交之前的所有内容,不是吗?
-
这在很大程度上取决于您使用的数据库。 Postgres 8.0+ 和 Oracle 正确支持事务。 MySQL 不能很好地使用它们,并且大多数其他数据库根本不支持它们。所以第一个问题是“你的数据库真的支持事务吗?”
-
@Gabriel,感谢您的回复。是的,它确实支持事务,我在 Postgresql 8.4 和 Sqlite 3 下测试了相同的代码。
-
除了关于这个函数本身的风格问题(即忽略有更好的编写方法的事实),为什么如果 super() 失败,项目会保存到数据库中?