我应该在Django的save方法中的哪里使用原子事务?

时间:2019-03-07 19:47:36

标签: python django transactions

这是对原子事务的适当使用吗?为什么或为什么不呢?

def save(self, **kwargs):
    try:
        with transaction.atomic:
            super(User, self).save(**kwargs)
            if self.image:
                img = Image.open(self.image.path)
                if img.height > 300 or img.width > 300:
                    output_size = (300, 300)
                    img.thumbnail(output_size)
                    img.save(self.image.path)
    except (OSError, IOError):
        self.image = None
        with transaction.atomic:
            super(User, self).save(update_fields=['image'])
        raise PValidationError('Image can`t be saved')

2 个答案:

答案 0 :(得分:0)

嗨,也许您可​​以使用这样的东西:

class MyModel(models.Model):
    # model definition

    def save(self, *args, **kwargs):
        transaction.set_autocommit(False)
        try:
            super(MyModel, self).save(*args, **kwargs)
            # do_other_things
        except:
            transaction.rollback()
            raise
        else:
            transaction.commit()
        finally:
            transaction.set_autocommit(True)

但是,这样的东西使用得更好:

class MyModel(models.Model):
    # model definition

    @transaction.atomic
    def save(self, *args, **kwargs):
        super(MyModel, self).save(*args, **kwargs)

请获取更多信息,请检查:@transaction.atomic

祝你好运.. !!

答案 1 :(得分:0)

我认为您实际上不需要两个原子事务中的任何一个。可以使用原子交易的最好例子是将钱从一个帐户转移到另一个帐户,例如:

def transfer_money(source_account, destination_account, quota):
    source_account.amount_of_money -= quota
    source_account.save()
    # K-BOOM
    destination_account.amount_of_money += quota
    destination_account.save()

如果# K-BOOM时刻出了什么问题怎么办?一个帐户将有较少的钱,而第二个帐户将没有应有的更多。

这就是为什么我们需要整个transfer_money函数是原子的:

@transaction.atomic
def transfer_money(source_account, destination_account, quota):
    source_account.amount_of_money -= quota
    source_account.save()
    # K-BOOM
    destination_account.amount_of_money += quota
    destination_account.save()