简体   繁体   中英

Concurrency control for inventory control

There are many similar questions related to my question. But I didnt find any satisfactory ans for my question. So I am putting this question in this forum.

I have a question in concurrency control in inventory management system. Say I have products A, B, C with quantity 2,3,4. And my application is multi user.

I have product page where user see the list of products and available quantity. and I have check out and payment page which may take some time to reach after product page.

Now if it is multi user web application and say user 1 has ordered 2 quantity product A but order is not yet placed, user 2 can still see A with 2 quantities.

Should I temporarily(configurable time) lock the 2 quantities of product A until order is placed? Is it a good design. If yes, should I lock in java or in the database?

No, it's not a good design because it lend itself for abuse and problems. What if a user (competitor?) locks all your products during the whole month? What if another person fills up his/her shopping cart with product and then decide it's too much money and just turns off his/her device?

Best alternatives are:

1) Tell the user how much availability is of each product, but also tell him/her it could be gone if an order is not placed soon. This should also incentive sales. Do lock/unlock your products after the payment page, ie when there is a business commit to the operation. If available quantities are not enough anymore, send the user back a previous page, updating the amounts to whetever is available.

2) Similar to 1), but you could also update availability from time to time. Or send warnings like "the stock of some items in your cart is running low". Again, this also could prompt sales.

3) Reserve ("lock") items as they are moved to a shopping cart, but not forever. Release the items after being locked for certain amount of time. Keep informed the user. The time-out can be per the whole shopping cart or per item.

It is very important to notice that any "lock" mentioned above is a "business lock/reservation". It doesn't need to be implemented in the form of locks or any other particular technical solution. For example, 3) above can be implemented by adding fields locked_by and locked_until . While you check/update/manipulate these fields you will probably need to do it within a "technical lock". After the checks/updates are done, the technical locks are released. However, a "business lock" could still in place because locked_until has not elapsed yet and any other code will check this field to consider the product available or not. Why? Because business rules mandate so (not because there is a technical lock in place, which in fact is not).

"Technical locks" should be very quick. "Business locks" can be much longer (but never forever; always define a time limit for them).

It's hard to tell if you should lock "in Java" on "in the database" with the very little information you give. Are you using Entity Beans, for example? What are your fault tolerance requirements? Etc.

That said, in the general case it's probably better to keep locks (as long as they are "business locks") in the database, for these main reasons:

  • Persistence (in case of a power failure). You should also provide a mechanism to recover shopping carts. Perhaps also storing them in the DB?
  • Ability to interface with other environments (ie a corporate ERP or fullfillment system).

Should I temporarily(configurable time) lock the 2 quantities of product A until order is placed? Is it a good design.

It depends on the conversation rate of your site, ie the number of checkouts/the number of payments. If you have a high conversation rate, you can pre lock the quantities to get a better user experience.

If yes, should I lock in java or in the database?

You need a global lock to guarantee the correctness. If you have multiple application servers, you have to put the lock in the database.

Inventory Management should be handled by a Custom System Built from ground up. You cannot rely simply on ACID compliance for performance reasons. Implementing Transactions on Inventory during the order is a very bad idea and is not scalable. I propose the following solution.

  1. An Inventory Management Backend App that updates the inventory as new items come in. Use row lock to update the inventory.
  2. An Inventory Management Micro Service App to give the inventory to Order Management System as it needs the inventory to finish the order and keep track of time out. a. If the order finished with Acknowledgement, The given inventory is already deducted by management system. We are good. b.If the order is not finished and no Acknowledgement is received, the given inventory is added back to the inventory system after the timeout (Typically 2 - 3 minutes). c. If the order has failed and acknowledgement is received that the order is failed, the given inventory is added back to the inventory system.

So, you don't lock the product rows until the order is finished. Instead, you do a soft lock on inventory and release if the order was not successful or failed due to an exception/App Failure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM