Где я должен использовать атомарные транзакции в методе сохранения Джанго? - PullRequest
1 голос
/ 07 марта 2019

Это правильное использование атомарных транзакций?Почему или почему нет?

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 голосов
/ 08 марта 2019

Я думаю, что вам не нужны никакие две атомарные транзакции.Лучший пример использования атомарной транзакции - это перевод денег с одного счета на другой, например:

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()
0 голосов
/ 07 марта 2019

привет, может быть, вы можете использовать что-то вроде этого:

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)

пожалуйста, для получения дополнительной информации проверьте: @action.atomic

удачи .. !!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...