У меня есть следующая часть кода, переопределяющего метод сохранения модели:
@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()
Ожидаемое поведение было бы: vote_down_count атрибута self.qa увеличен одним, но если какое-либо исключение происходит в супер (сам), сохраняют метод откаты транзакции (который означает сам qa.vote_down_count + = 1, не фиксируется в базе данных).
Фактическое поведение: сам qa.vote_down_count + = 1 посвящает себя базе данных, даже если исключение IntegrityError повышает от супер (сам), сохраняют.
Какие-либо мысли?
Почему бы просто не сделать:
@transaction.commit_manually
def save(self, *args, **kwargs):
try:
super(self.__class__, self).save(*args, **kwargs)
self.qa.vote_down_count += 1
self.qa.save()
except:
transaction.rollback()
raise
else:
transaction.commit()
Вот как документация предлагает это сделать, хотя они говорят делать это в функции представления, поэтому вам может не понадобиться @transaction.commit_manually
в методе save()
, вместо этого поместив его в представление.
Попробуйте использовать точек сохранения . Что-то вроде этого:
def save(self, *args, **kwargs):
try:
sid = transaction.savepoint()
self.qa.vote_down_count += 1
self.qa.save()
super(self.__class__, self).save(*args, **kwargs)
except:
transaction.rollback(sid)
raise
else:
transaction.commit(sid)