Избегайте условий гонки в сценариях электронной коммерции - PullRequest
4 голосов
/ 02 августа 2010

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

Так что мне было интересно, есть ли способ исправить это? Я думал о создании «маркера» в начале процесса, то есть он проверил бы инвентарь и, если он был продан, маркировал бы продукт как таковой, таким образом предотвращая его покупку другими сессиями. Но это также создает дополнительную проблему: если что-то происходит на стороне клиента, что заставляет его отменить промежуточный процесс (потеря мощности и т. Д.), То даже если продукт помечен как проданный, он фактически не продавался с момента оформления заказа. процесс не закончился. Если это будет продолжаться, то будет избыток продуктов. Во-вторых, сеанс также может проверять наличие запасов, пока другой сеанс помечает его как проданный, поэтому первый сеанс будет продолжаться, даже если второй сеанс уже купил его. Это возвращает нас к первоначальной проблеме.

Я смотрю на блокировки таблиц в конце базы данных, но я не уверен, что это лучшая идея. Любые предложения будут высоко оценены!

Спасибо, dyip

Ответы [ 2 ]

1 голос
/ 02 августа 2010

У вас может быть отказоустойчивый вариант, когда заказ оформляется, когда пользователь выписывается, но с кредитной карты пользователя фактически не взимается плата, пока его заказ не будет отправлен. Затем, в случаях, когда запасы закончились, вы можете просто отправить электронное письмо этим клиентам и сказать им: «Извините, мы продали X, с вас не будет взиматься плата и т. Д.».

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

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

0 голосов
/ 24 октября 2014

Я бы предложил вам сделать следующее:

  1. Не уменьшать наличие товара на складе, когда он добавлен в корзину; Вы не хотите пропустить ни одной возможной будущей продажи;
  2. Когда пользователь решает начать процесс оформления заказа, на бэкэнде вы можете пометить все продукты в корзине для покупок как зарезервированные , добавив их в отдельную таблицу базы данных.
  3. Если пользователь B начинает процесс оформления заказа через некоторое время, то вы можете проверить наличие каждого продукта в корзине еще раз, например:

    productAvailability - quantityReservedForThisProduct >= quantityRequested
    

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

    В двух словах: если кто-то еще начал процесс оформления заказа, он автоматически резервирует эти продукты.

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

  5. Кроме того, мы не хотим находиться в ситуации, когда пользователь зарезервировал продукты (т.е. начал процесс оформления заказа), но никогда не покупал их. По этой причине вы можете ввести механизм TTL . Таким образом, через фиксированные интервалы вы можете удалить процессы оформления заказа, которые превышают фиксированное количество времени.

    Например, если пользователь запустил процесс оформления заказа, но, скажем, через 10 минут он еще не завершил его, удалите его из базы данных и выпустите зарезервированные продукты.

Мне кажется, что я еще не проверял этот подход;

...