Flask-sqalchemy with_for_update () возвращает старые данные

У меня есть ситуация в моем приложении Flask, когда мне нужно генерировать увеличивающиеся числа против потребителя. Для этого у каждого потребителя есть строка в отдельной таблице, в которой до сих пор хранится генератор чисел.

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

Я делаю with_for_update по запросу модели. Данные читаются, затем обновляются, однако при втором запросе читаются старые данные. Пытался установить более высокий уровень изоляции БД (SERIALIZABLE), но не сработало.

Образец кода:

obj = NumberGenerator.query.filter(
    NumberGenerator.consumer_id == consumer_id
).with_for_update().first()

obj.number = obj.number + 1

db.session.add(obj)
db.session.commit()

Второй запрос читает старые данные. Я не могу понять, почему это происходит. Я попробовал тот же подход через iPython, и он работал безупречно. Пробовал писать необработанные запросы MySQL с помощью MySQLdb, это тоже сработало. Много искал на разных форумах (включая переполнение стека), в документации по пакетам и ничего не нашел.

Flask-SQLAlchemy version: 2.3.2

MySQL version: 5.6

1
0
747
1

Ответы 1

Я столкнулся с той же проблемой. См. Следующую проблему для решения https://github.com/sqlalchemy/sqlalchemy/issues/4774

Короче говоря, самый простой способ - добавить populate_existing() в запрос

obj = NumberGenerator.query.filter(
    NumberGenerator.consumer_id == consumer_id
).with_for_update().populate_existing()

Другие вопросы по теме