Rumah > Soal Jawab > teks badan
新客领取优惠券逻辑
判断是否新客
若为新客 查询数据库是否已领取过
未领取过 给用户发券
同一用户并发领券的情况下 会有超领的情况 因为并发进来时查询数据库均没有领取记录
而又不能针对用户和优惠券做唯一索引 因为有些券允许用户领取多张。
于是决定采用redis计数来防同一用户并发超领 新客领券逻辑改成如下
判断是否新客
若为新客 基于用户ID计数 incr {user_id}_receive_count
如果计数大于1 表示同一用户并发领券 直接返回
如果计数==1 表示第一次领取
查询数据库是否已领取过
未领取过 给用户发券
上述逻辑没有问题 但纠结该如何设置计数key的过期时间
设置过期时间为1分钟
基本上大部分并发操作都是在同一秒 过期时间1分钟能满足要求了
设置过期时间为1小时
万一数据库负载高呢 并不能在一分钟内完成一次领券事务操作 如双十一这种场景 还是设的长一点 更保险一点 不管怎样 1小时足够完成一次领券事务操作了吧 但时间设的长了 会不会因为其他原因(如网络超时)导致领券失败回滚 用户要等一小时后 才能重新领券
有没其他防并发领取方案呢? 可以不用纠结这种过期时间的设置呢。
PHP中文网2017-04-27 09:04:40
Adalah disyorkan untuk memisahkan penghakiman mencegah keterlaluan dan menilai sama ada pelanggan baharu ialah pelanggan baharu
Kolar super anti-konkurensi boleh digunakan seperti berikut (dikunci Ingat untuk memadamkan kunci (lepaskan kunci) selepas setiap operasi selesai
// 操作的原子性,如该key在有效时间30秒被设置过返回0,一般请求超时为30秒
$redis->set($key, 1, array("NX", "EX"=>'30'));
Untuk menentukan sama ada ia adalah pelanggan baharu (sama ada pengguna telah menerimanya sebelum ini, masa yang sah ditetapkan pada penghujung acara), anda boleh menetapkan KUNCI baharu sebagai status penerimaan pengguna dan ia akan dipulangkan terus kepada pengguna yang telah menerima diskaun (mengejar Untuk prestasi serentak, pertanyaan pangkalan data tidak disambungkan)
Dapatkan kupon (masukkan kupon ke dalam baris gilir terlebih dahulu dan dapatkannya dari baris gilir, bukan dari pangkalan data. Kelebihan di sini ialah data baris gilir akan hilang sebaik sahaja ia diambil, dan akan ada tiada situasi lebihan terima), tulis Masukkan baris gilir redis
Baris gilir penggunaan proses latar belakang, saya menggunakan jenis penyekatan senarai terpaut untuk penggunaan (simpan maklumat pengumpulan ke dalam pangkalan data, dan tanya serta tentukan sama ada pengguna telah menerima kupon sebelum memasuki pangkalan data)
黄舟2017-04-27 09:04:40
Pelan khusus masih perlu dilaksanakan mengikut perniagaan
Jika perniagaan tidak memerlukan 100%, setiap orang hanya boleh menerima satu kupon, dan kluster Redis anda sangat tersedia Maka sudah cukup untuk menyekatnya dengan Redis
, masa tamat tempoh Kunci tertentu, dsb Muat turun aktiviti akan menjadi tidak sah secara keseluruhan, kerana ini adalah penyelesaian yang tidak termasuk dalam perpustakaan, jadi jika anda perlu menentukan sama ada untuk mengulangi permintaan, anda perlu bergantung pada data dalam Redis (bagaimana jika Redis hang Walaupun Redis mempunyai fungsi kegigihan yang tidak sempurna, kerugian Jumlah data agak kecil, jika perniagaan membenarkannya, ia masih boleh diterima), tetapi banyak senario perniagaan memerlukan pengelogan
Keperluan perniagaan memerlukan satu orang mesti mempunyai satu kupon (nilai muka kupon mungkin sangat besar), jadi saya masih akan menggunakan penyelesaian Redis
subjek Selepas menilai bahawa ia adalah kali pertama, terus masukkan/kemas kini pangkalan data ( Akan ada penyelesaian tak segerak di sini, tetapi penyelesaian tak segerak juga akan muncul. Penyelesaian tak segerak juga akan menghadapi masalah yang serupa dengan 1: kehilangan data, ia boleh dijamin bahawa setiap orang hanya boleh menerima satu kupon (ditentukan oleh pangkalan data) memastikan ketekalan data). Seperti yang dikatakan oleh penanya, sebenarnya, anda tidak perlu membatalkan perkara dalam Redis, kerana jika pengguna berulang kali dengan niat jahat meminta untuk menarik kupon, Redis boleh terus menyekatnya tanpa pergi ke pangkalan data untuk bertanya (terdapat masalah lain di sini. Penyelesaiannya adalah untuk mengemas kini cache dahulu Kemas kini pangkalan data sekali lagi, jadi anda perlu mempertimbangkan situasi tidak normal di mana kemas kini cache berjaya tetapi kemas kini pangkalan data gagal Jika pangkalan data tidak normal, anda perlu mengosongkan cache yang sepadan dengan Kunci )
Jika anda benar-benar tidak dapat mengendalikannya (perkakasan tidak dapat bersaing), anda boleh menggunakan baris gilir untuk menyelesaikan masalah dan menggunakan baris gilir untuk memotong puncak
Penyelesaian @大woo juga boleh dilaksanakan, tetapi anda perlu mempertimbangkan Redis
situasi luar biasa ini pada satu ketika
滿天的星座2017-04-27 09:04:40
Fungsi yang disebut oleh @大woo sebenarnya serupa dengan jualan kilat yang saya tulis sebelum ini. Anda boleh lihat:
Fungsi penting untuk produk e-dagang: jualan kilat dan lelongan
淡淡烟草味2017-04-27 09:04:40
Saya mabuk jika anda berani menggunakan pangkalan data nosql untuk perkara seperti ini.
Adalah disyorkan untuk mempelajari teori pangkalan data terlebih dahulu, memfokuskan pada konsep transaksi, beberapa tahap pengasingan transaksi, kunci baris dan kunci meja, dan kemudian gunakan pangkalan data hubungan tradisional untuk melakukan ini.
Jika prestasi pelayan pangkalan data tidak mencukupi, maka reka bentuk seni bina jadual mendatar, dengan pelayan berbeza, setiap pelayan bertanggungjawab untuk sebahagian daripada data pengguna. Sumber teori jadual tahap ialah bab cincang bagi struktur data peringkat sarjana Anda boleh melihatnya.