Tutorial :Avoid race conditions in eCommerce scenarios



Question:

My client has a ecommerce website that sells electronics, and there has been situations where a product is sold more times than they have in their inventory. This is because if two users buy a product at the same time when there is only one product left in stock, one session does not finish registering the product as sold out before the other session starts(so it continues as normal, thinking there is one left) even though there is a check in place at the beginning of the process. This would obviously cost money (chargeback fees, refunds, etc.) and inconvenience for the consumers.

So I was wondering if there is anyway to fix this? I thought of creating a "marker" at the beginning of the process, i.e. it would check for inventory and if sold out, it would label the product as such thus preventing other sessions from buying it. But this also creates more problem: if something happens on the customer's side that would cause them to cancel mid-process (lost of power, etc.), then even though the product is marked as sold, it did not actually sell since the checkout process did not finish. If this keeps happening, there would be an overstock of products. Secondly, it is also possible for a session to check for inventory WHILE another session is marking it as sold, thus the first session would continue even though the second session already bought it. This leads us back to the original problem.

I am looking at table lockings in the database-end, but I am not sure if thats the best idea. Any suggestions would be highly appreciated!

Thanks, dyip


Solution:1

You could have a failsafe such that an order is placed when the user checks out, but the user's credit card is not actually charged until their order ships. Then, for cases where the inventory has run out, you could just email those customers and tell them "Sorry, we have sold out of X, you will not be charged, etc".

You could give them some kind of discount on their next order as compensation, but this process would avoid any chargeback fees, refunds, etc as they are never actually charged for the order that was not in stock.

Of course, it sounds like this would change how orders are handled by the site, and it would necessitate having someone enter information into the system after each order is prepared. Also, you would need some validation of the card to know it is valid before placing the order, to prevent fraud - although presumably the site is doing this already?


Solution:2

I would suggest you to do the following:

  1. Do not decrement the stock availability of a product when it's added to the shopping cart; You don't want to miss any possible future sell;
  2. When user decides to start the checkout process then on the back-end you can mark all products in the shopping cart as reserved by adding them to a separate database table.
  3. If the User B starts the checkout process some time later, then you can check the availability of each product in the cart one more time, like this:

    productAvailability - quantityReservedForThisProduct >= quantityRequested  

    If the above condition is false, it means that someone else has already expressed the will to buy it. So you can you let your user know about the current condition.

    In an nutshell, that if someone else has started the checkout process he automatically reserves those products.

  4. Then when the first user's payment is successful, we update both the table with the reserved products and the one that stores the actual products i.e decrement the stock availability.

  5. In addition, we don't want to be in a situation where the user has reserved the products (i.e. started the checkout process) but never purchased them. For that reason you can introduce a TTL mechanism. So, in fixed intervals you can remove the checkout processes that exceed a fixed amount of time.

    For example, if user started a checkout process but after, say 10 minutes it has not completed it yet, then remove it from the database and release the reserved products.

Bare in my mind that I have not tested this approach yet;


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »