使用redis秒杀出现产品超发现象求解?
最近在做一个秒杀活动,处于性能和响应速度的考虑,使用了redis。写的时候就特别注意了杜绝超发现象,基于redis理论的cas(check and set)乐观锁,想着应该能够杜绝该问题,但是还是出现了,很疑惑求大神帮助,具体的代码大致如下:
<code><?php header("content-type:text/html;charset=utf-8"); $redis = new redis(); $result = $redis->connect('10.10.10.119', 6379); $mywatchkey = $redis->get("mywatchkey"); $rob_total = 100; //抢购数量 if($mywatchkeywatch("mywatchkey"); $redis->multi(); //设置延迟,方便测试效果。 sleep(5); //插入抢购数据 $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 "抢购成功!<br>"; echo "剩余数量:".($rob_total-$mywatchkey-1)."<br>"; echo "用户列表:<pre class="brush:php;toolbar:false">"; var_dump($mywatchlist); }else{ echo "手气不好,再抢购!";exit; } } ?>
回复内容:
最近在做一个秒杀活动,处于性能和响应速度的考虑,使用了redis。写的时候就特别注意了杜绝超发现象,基于redis理论的cas(check and set)乐观锁,想着应该能够杜绝该问题,但是还是出现了,很疑惑求大神帮助,具体的代码大致如下:
<code><?php header("content-type:text/html;charset=utf-8"); $redis = new redis(); $result = $redis->connect('10.10.10.119', 6379); $mywatchkey = $redis->get("mywatchkey"); $rob_total = 100; //抢购数量 if($mywatchkeywatch("mywatchkey"); $redis->multi(); //设置延迟,方便测试效果。 sleep(5); //插入抢购数据 $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 "抢购成功!<br>"; echo "剩余数量:".($rob_total-$mywatchkey-1)."<br>"; echo "用户列表:<pre class="brush:php;toolbar:false">"; var_dump($mywatchlist); }else{ echo "手气不好,再抢购!";exit; } } ?>
我觉得这个代码在高并发的情况,仍然会出现超卖现象。假如:只剩 1个奖品的时候,有三个人同时执行 $redis->watch("mywatchkey")
拿到的数据是 99 ,那么就出现超卖现象了。
由于redis
是单线程读取,那么就用最简单的队列实现吧。
在抽奖前先把奖品数量,写入
redis
队列award:100
// 长度为100的 list ,值只是作为是否中奖并发抽奖
<code>$award = $redis->lpop('award:100'); // 由于队列只有100个值,可以确保只有100个人中奖 if(!$award){ echo "手气不好,再抢购!";exit; } // 剩下就是中奖操作的事情了</code>
sleep(5);
你公司还收不收人?
考虑一下这种情况。
mywatchkey=99
用户A请求mywatchkey得到99,
用户B请求mywatchkey得到99,
当A,B请求完成之后,mywatchkey应该为多少呢。。101,还是100?
你这个是经典的Check-then-Act错误
首先问一下你这个代码的“超卖”结果是$mywatchkey > 100了 (我认为不可能出现)
还是$mywatchkey =100时候同时有两个页面出现“抢购成功!“
我没有对这个代码进行测试,我只是猜测会不会是以下的情况:
1.Session A : 进行mywatchkey检查,此时mywatchkey = 99
2.Session B : 处理完 mywatchkey以后,此时mywatchkey=100 但是并不影响Session A的后续操作
补充两个连接,看看吧,或许有收获
transactions-and-watch-statement-in-redis
redis-watch-multi-exec-by-one-client
如果这事要从根本上解决,请先学习:
1.锁。
2.传统数据库事务。
然后再学习Redis与传统数据库的区别。

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

PHP 8.4 membawa beberapa ciri baharu, peningkatan keselamatan dan peningkatan prestasi dengan jumlah penamatan dan penyingkiran ciri yang sihat. Panduan ini menerangkan cara memasang PHP 8.4 atau naik taraf kepada PHP 8.4 pada Ubuntu, Debian, atau terbitan mereka

Kod Visual Studio, juga dikenali sebagai Kod VS, ialah editor kod sumber percuma — atau persekitaran pembangunan bersepadu (IDE) — tersedia untuk semua sistem pengendalian utama. Dengan koleksi sambungan yang besar untuk banyak bahasa pengaturcaraan, Kod VS boleh menjadi c

Tutorial ini menunjukkan cara memproses dokumen XML dengan cekap menggunakan PHP. XML (bahasa markup extensible) adalah bahasa markup berasaskan teks yang serba boleh yang direka untuk pembacaan manusia dan parsing mesin. Ia biasanya digunakan untuk penyimpanan data

Rentetan adalah urutan aksara, termasuk huruf, nombor, dan simbol. Tutorial ini akan mempelajari cara mengira bilangan vokal dalam rentetan yang diberikan dalam PHP menggunakan kaedah yang berbeza. Vokal dalam bahasa Inggeris adalah a, e, i, o, u, dan mereka boleh menjadi huruf besar atau huruf kecil. Apa itu vokal? Vokal adalah watak abjad yang mewakili sebutan tertentu. Terdapat lima vokal dalam bahasa Inggeris, termasuk huruf besar dan huruf kecil: a, e, i, o, u Contoh 1 Input: String = "TutorialSpoint" Output: 6 menjelaskan Vokal dalam rentetan "TutorialSpoint" adalah u, o, i, a, o, i. Terdapat 6 yuan sebanyak 6

Jika anda seorang pembangun PHP yang berpengalaman, anda mungkin merasakan bahawa anda telah berada di sana dan telah melakukannya. Anda telah membangunkan sejumlah besar aplikasi, menyahpenyahpepijat berjuta-juta baris kod dan mengubah suai sekumpulan skrip untuk mencapai op

CMS bermaksud Sistem Pengurusan Kandungan. Ia adalah aplikasi perisian atau platform yang membolehkan pengguna mencipta, mengurus dan mengubah suai kandungan digital tanpa memerlukan pengetahuan teknikal lanjutan. CMS membolehkan pengguna membuat dan menyusun kandungan seperti teks, imej, video dan dokumen dengan mudah serta menerbitkannya di tapak web atau platform digital lain.

Array adalah struktur data linear yang digunakan untuk memproses data dalam pengaturcaraan. Kadang -kadang apabila kita sedang memproses tatasusunan kita perlu menambah unsur -unsur baru ke array yang sedia ada. Dalam artikel ini, kami akan membincangkan beberapa cara untuk menambah unsur -unsur ke akhir array dalam PHP, dengan contoh kod, output, dan analisis kerumitan masa dan ruang untuk setiap kaedah. Berikut adalah cara yang berbeza untuk menambah elemen ke array: Gunakan kurungan persegi [] Dalam PHP, cara untuk menambah unsur -unsur ke akhir array adalah menggunakan kurungan persegi []. Sintaks ini hanya berfungsi dalam kes -kes di mana kita mahu menambah hanya satu elemen. Berikut adalah sintaks: $ array [] = nilai; Contoh

Nexo Exchange: Platform Pinjaman Cryptocurrency Swiss Analisis mendalam Nexo adalah platform yang menyediakan perkhidmatan pinjaman cryptocurrency, menyokong gadai janji dan pinjaman lebih daripada 40 aset crypto, mata wang fiat dan stablecoins. Ia menguasai pasaran Eropah dan Amerika dan komited untuk meningkatkan kecekapan, keselamatan dan pematuhan platform. Ramai pelabur ingin tahu di mana pertukaran Nexo didaftarkan, dan jawapannya ialah: Switzerland. Nexo ditubuhkan pada tahun 2018 oleh syarikat Swiss Fintech Credissimo. Nexo Exchange Lokasi dan Peraturan Geografi: Nexo beribu pejabat di Zug, Switzerland, rantau yang mesra cryptocurrency yang terkenal. Platform ini secara aktif bekerjasama dengan pengawasan pelbagai kerajaan dan telah berada di Rangkaian Penguatkuasaan Undang -undang Jenayah Kewangan AS (FINCEN) dan Kewangan Kanada
