需求是这样的:
用户每天最多领取礼包3次,每次insert一条记录,但是在并发的情况下会超出3次,如果解决?
有个已知的方法如下,但是并发下会产生死锁
INSERT INTO t_test (gift_id, user_id, `date`) SELECT v_gift_id, v_user_id, v_date FROM dual WHERE not exists (select * from t_test where `user_id` = v_user_id and `date` = v_date GROUP BY `user_id`, `date` HAVING count(*) > 2);
Seperti yang @junze katakan, ia biasanya dilakukan dengan
redis
.Sebagai contoh, simpan bilangan kali untuk setiap pengguna
redis
dalaminsert
. Jika formatkey
ialahuser:count
Mula-mula semak nilai
count
setiap kali, jika kurang daripada 3, lakukan sisipan dan nilaikan hasilinsert
Jika sisipan berjaya, jalankankey
untukuser:count
incr
. ,incr user:count
, dan penulisan gagalincr
tidak dilaksanakan.Ini boleh mengelakkan konkurensi tinggi melebihi 3.
Pada masa yang sama, anda boleh menetapkan masa tamat tempoh
key
untuk iniexpire user:count 60*60*24
kepada 1 hari Selepas sehari, kunci akan dipadamkan dan dimulakan semula pada hari berikutnya.Gunakan jenis redis untuk mengira Redis mempunyai sokongan yang lebih baik untuk konkurensi tinggi
MySQL tidak boleh melakukan ini untuk anda Anda boleh meletakkan nombor pakej hadiah pengguna dalam cache, menambah beberapa pemalar sebagai kunci cache berdasarkan ID pengguna, menyimpan nombor di dalamnya dan mendapatkannya dari cache setiap kali. ia dimasukkan. Keluarkan bilangan kali dan nilaikan sama ada ia kurang daripada nombor anda, teruskan. Jika anda meneruskan, nombor akan ditambah satu selepas dimasukkan dan diletakkan dalam cache.
Adalah disyorkan untuk melakukannya pada lapisan logik
Mysql nampaknya tidak mempunyai mekanisme ini, dan saya merasakan kawalan ini juga merupakan kawalan logik
Jika anda mesti menggunakan mysql untuk melakukannya, gunakan transaksi untuk memastikannya.