需求是这样的:
用户每天最多领取礼包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);
Comme l'a dit @junze, cela se fait généralement avec
redis
.Par exemple, stockez le nombre de fois pour chaque utilisateur
redis
dansinsert
. Si le formatkey
estuser:count
Vérifiez d'abord la valeur de
count
à chaque fois, si elle est inférieure à 3, effectuez l'insertion et jugez le résultat deinsert
Si l'insertion est réussie, exécutezkey
pouruser:count
incr
. ,incr user:count
, et l'écriture échoueincr
n'est pas exécutée.Cela peut éviter une concurrence élevée dépassant 3.
En même temps, vous pouvez régler le délai d'expiration
key
pour celaexpire user:count 60*60*24
à 1 jour. Après un jour, la clé sera supprimée et réinitialisée le lendemain.Utilisez le type de chaîne de Redis pour compter. Redis prend mieux en charge la concurrence élevée
MySQL ne peut pas faire cela à votre place. Vous pouvez mettre le nombre de paquets cadeaux de l'utilisateur dans le cache, ajouter des constantes comme clé de cache en fonction de l'ID de l'utilisateur, y stocker le numéro et le récupérer du cache à chaque fois. il est inséré. Retirez le nombre de fois et jugez s'il est inférieur à votre numéro, continuez. Si ce n'est pas inférieur à votre numéro, continuez. Si vous continuez, le nombre sera augmenté de un après insertion et placé dans le cache.
Il est recommandé de le faire au niveau de la couche logique
Mysql ne semble pas avoir ce mécanisme, et j'ai l'impression que ce contrôle est aussi un contrôle logique
Si vous devez utiliser MySQL pour le faire, utilisez des transactions pour vous en assurer.