How can I solve the problem of product overuse during the second kill of redis?

Source: Internet
Author: User
Recently, I was engaged in a second kill activity, considering the performance and response speed, using redis. When writing, I paid special attention to the prevention of supersending. the cas (checkandset) optimistic lock based on redis theory should be able to prevent this problem, but it still appeared, i'm confused. please help me ,... recently, I was engaged in a second kill activity, considering the performance and response speed, using redis. When writing, I paid special attention to the prevention of supersending. the cas (check and set) optimistic lock based on redis theory should be able to prevent this problem, but it still appeared, I am confused. please help me. the specific code is roughly as follows:


  Connect ('10. 10.10.119 ', 6379); $ mywatchkey = $ redis-> get ("mywatchkey"); $ rob_total = 100; // quantity of purchases if ($ mywatchkey <$ rob_total) {$ redis-> watch ("mywatchkey"); $ redis-> multi (); // sets the latency to facilitate testing. Sleep (5); // Insert the snapped up data $ redis-> hSet ("mywatchlist", "user_id _". mt_rand (1, 9999), time (); $ redis-> set ("mywatchkey", $ mywatchkey + 1); $ rob_result = $ redis-> exec (); if ($ rob_result) {$ mywatchlist = $ redis-> hGetAll ("mywatchlist"); echo "snapped up!
"; Echo" remaining quantity: ". ($ rob_total-$ mywatchkey-1 )."
"; Echo" user list:
"; Var_dump ($ mywatchlist);} else {echo" bad luck, buy again! "; Exit ;}}?>

Reply content:

Recently, I was engaged in a second kill activity, considering the performance and response speed, using redis. When writing, I paid special attention to the prevention of supersending. the cas (check and set) optimistic lock based on redis theory should be able to prevent this problem, but it still appeared, I am confused. please help me. the specific code is roughly as follows:


   Connect ('10. 10.10.119 ', 6379); $ mywatchkey = $ redis-> get ("mywatchkey"); $ rob_total = 100; // quantity of purchases if ($ mywatchkey <$ rob_total) {$ redis-> watch ("mywatchkey"); $ redis-> multi (); // sets the latency to facilitate testing. Sleep (5); // Insert the snapped up data $ redis-> hSet ("mywatchlist", "user_id _". mt_rand (1, 9999), time (); $ redis-> set ("mywatchkey", $ mywatchkey + 1); $ rob_result = $ redis-> exec (); if ($ rob_result) {$ mywatchlist = $ redis-> hGetAll ("mywatchlist"); echo "snapped up!
"; Echo" remaining quantity: ". ($ rob_total-$ mywatchkey-1 )."
"; Echo" user list:
"; Var_dump ($ mywatchlist);} else {echo" bad luck, buy again! "; Exit ;}}?>

I think this code will still be sold out in high concurrency. Assume that when there is only one prize, three people will execute the prize at the same time.$redis->watch("mywatchkey")The data obtained is 99, so the sales volume is oversold.

BecauseredisIt is read by a single thread, so use the simplest queue.

  1. Write the number of prizes into the lotteryredisQueueaward:100// List with a length of 100. The value is only used as whether to win the prize.

  2. Concurrent lottery

$ Award = $ redis-> lpop ('award: 100'); // since the queue has only 100 values, make sure that only 100 people win the prize if (! $ Award) {echo "bad luck, buy again! "; Exit;} // The rest is about the winning operation.

Sleep (5 );
Isn't your company accepting people?

Consider this situation.
Mywatchkey = 99
User A requests mywatchkey to get 99,
User B requests mywatchkey to get 99,
What is the value of mywatchkey after A and B are completed .. 101, or 100?

This is a classic Check-then-Act error.

First, let's ask if the code's "superselling" result is $ mywatchkey> 100 (I don't think it will happen)
Or $ mywatchkey = 100 at the same time there are two pages that show "flash sale successful! "
I didn't test the code. I just wondered if it would be the following:

1. Session A: check mywatchkey. at this time, mywatchkey = 99

2. Session B: after mywatchkey is processed, mywatchkey = 100 does not affect subsequent operations of Session.

Add two more connections. let's take a look. There may be gains.

Transactions-and-watch-statement-in-redis
Redis-watch-multi-exec-by-one-client

If you want to solve this problem fundamentally, first learn:

1. lock.

2. traditional database transactions.

Then we will learn the difference between Redis and traditional databases.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.