Django3 использует MySQL - чтение и обновление в одной транзакции - PullRequest
0 голосов
/ 30 апреля 2020

Уровень изоляции по умолчанию не позволяет работать следующему коду; отдельные процессы могут считывать одно и то же значение, устанавливать одно и то же значение и вызывать ошибочный подсчет.

def next_id():
    with transaction.atomic():
        db_counter = Counter.objects.filter(name=name).first()
        if not db_counter:
            # Create count if not exists
            db_counter = Counter.objects.create(name=name, count=0)
        count = db_counter.count
        db_counter.count = count + 1
        db_counter.save()
    return count

Некоторые вещи, на которые я смотрел:

  • Установка уровня изоляции на serializable работает, но я боюсь, что это слишком ограничительно. Остальная часть приложения работает нормально с repeatable read.
  • . select_for_update может работать, но я не знаю, как применять его в случае, если счетчик отсутствует, и запись должна быть добавлена.
  • Я проследил через код Django / MySQL с помощью отладчика: я не уверен, что transaction.atomic() что-то делает, я не вижу, чтобы он испускал START TRANSACTION.

Как попросить Django начать транзакцию? Спасибо.

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