问题
When I click on 'Place Order' I have begun the transaction and set the column is_payment_processing to True before taking the user to the merchant website and then there could be three possibilities:
- User landed on success callback page
- User landed on failure callback page
- User landed neither on success nor on failure callback coz he closed the window.
In Third Scenario: The product will remain in the state where is_payment_processing is True. And, other users who attempt to check out the same product will not be able to do so. But in this case, I may lose some customers and cause some inconvenience.
Thinking to have a cron job to run every minute which will track the last modification time of that column and if it is not been altered for more than 3 minutes then set that flag to False.
What should be the best approach here? How in general scenario this is implemented? (Concurrency Control)
Another Thought In Mind: Visit this question
回答1:
Ideally you should have a stock
field in your Product
model to keep the number of quantities available for that product.
When someone places an order, a separate order
instance should be created with the number of quantities of the Prodduct
specified. The stock should only be reduced once the callback is received for that order
or a webhook is received confirming the payment.
This would not prevent other customers from placing orders for the same product until the item has actually been sold.
Another approach could be to reduce the stock when the customer goes to the callback page and release the stock if the payment is not received within certain duration of time. Background task would be required for this.
Note: use F
object from django.models
while reducing the stock in order to reduce the stock from the DB value and not the instance attribute.
回答2:
Cron seems to be the best approach if you are able to(If you are on a shared host, many providers dont allow you any crons)
I might make the cron intelligent by checking if the transaction is still in progress. (Here I am assuming I have a mechanism to do so)
EDIT: Please note, locking the inventory once the payment transaction is in progress, is pretty standard
来源:https://stackoverflow.com/questions/58576712/concurrent-payment-control