SQLAlchemy (Postgresql) - условия гонки

2

Мы пишем систему инвентаризации, и у меня есть некоторые вопросы о sqlalchemy (postgresql) и транзакциях/сеансах. Это веб-приложение, использующее TG2, но не уверен, что это важно, но много информации никогда не бывает плохой.

  • Как можно убедиться, что при изменении инвентаря, который я не запускаю в условиях гонки. Если я правильно понимаю, если пользователь наступает, чтобы уменьшить инвентарь на предмет, чтобы сказать 0, а пользователь два также пытается уменьшить инвентарь до 0, то если сеанс пользователя 1 не был еще установлен, тогда пользователь начинает два начального инвентарного номера быть таким же, как пользовательский, приводящий к условию гонки, когда оба фиксируют, один переписывает другой, вместо того, чтобы иметь составной эффект.

  • Если бы я хотел использовать последовательность postgresql для таких вещей, как номера заказов/счетов, как я могу получить/установить следующие значения из sqlalchemy без использования условий гонки?

EDIT: Я думаю, что нашел решение, которое мне нужно использовать with_lockmode, используя для обновления или для совместного использования. Я собираюсь оставить открытым для получения дополнительных ответов или для других, чтобы исправить меня, если я ошибаюсь.

ТИА

Теги:
web-applications
sqlalchemy
turbogears2

2 ответа

3
Лучший ответ

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

На порядковых номерах нет условия гонки. Сохраните запись, в которой используется порядковый номер, который DB автоматически назначит.

Edit:

Обратите внимание, что, поскольку Limscoder указывает, вам необходимо установить уровень изоляции в Повторяемое чтение.

  • 0
    Так что, если на складе 5 товаров. Сессия / транзакция 1 будет уменьшать это на 2 (продано 2 из них), а Сессия / транзакция 2 будет проверять запас, чтобы увидеть, сколько их. Если транзакция 2 выполняется до завершения транзакции 1, знает ли транзакция 2, что на складе 3, или она все еще видит 5?
  • 0
    То, что вы хотите сделать, это запросить один раз, чтобы показать, сколько товаров на складе. Оба пользователя увидят 5 товаров на складе, оба просят 3 товара. Когда они делают запрос, вы начинаете транзакцию, запрашиваете количество элементов, чтобы убедиться, что вы можете заполнить запрос, затем попытайтесь зафиксировать транзакцию. Если две транзакции происходят одновременно, все запросы на количество элементов возвращают 5. Транзакция, которая была бы ошибкой в состоянии гонки, не будет выполнена. Вы обрабатываете этот сбой, перезапуская транзакцию, обнаруживая, что не хватает элементов, и сообщаете об этом пользователю.
Показать ещё 3 комментария
1

Установите сценарий, о котором вы говорите, и посмотрите, как его обрабатывает ваша конфигурация. Просто откройте два отдельных соединения, чтобы проверить его.

Также прочитайте в разделе FOR UPDATE "Обновить" , а также уровень изоляции транзакции Уровень изоляции

Ещё вопросы

Сообщество Overcoder
Наверх
Меню