Избегайте условий гонки в сценариях электронной коммерции

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

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

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

Спасибо, Дип


person Dyip302    schedule 02.08.2010    source источник
comment
Простое решение, сделайте чек, когда они платят, чтобы увидеть, есть ли товар на складе. eBay делает это при мгновенной оплате, купите сейчас, там написано, что акции не будут вам гарантированы, пока вы не заплатите, я говорю, что используйте то же решение.   -  person Ben Everard    schedule 02.08.2010
comment
По мнению большинства потребителей, они платили, когда нажимали кнопку «Отправить» при оформлении заказа. На самом деле мы не взимаем плату до тех пор, пока товар не будет отправлен, но мы хотим, чтобы они не покупали товар, когда его нет в наличии.   -  person Dyip302    schedule 02.08.2010
comment
... проверить на месте в начале процесса.. Мне кажется, вам нужно сделать дополнительную проверку, когда они нажимают кнопку отправки при оформлении заказа. - или ты уже это делаешь?   -  person MrWhite    schedule 02.08.2010


Ответы (2)


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

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

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

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

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

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

    productAvailability - quantityReservedForThisProduct >= quantityRequested
    

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

    Короче говоря, если кто-то другой начал процесс оформления заказа, он автоматически резервирует эти продукты.

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

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

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

Имейте в виду, что я еще не тестировал этот подход;

person ppoliani    schedule 24.10.2014