J'utilise une liste Redis pour créer un limiteur et cela fonctionne comme prévu la plupart du temps, mais récemment j'ai découvert que certaines clés n'ont pas de délai d'expiration. Idéalement, je "pousserais" les valeurs dans la liste et définirais l'heure d'expiration dans une transaction et j'utiliserais également "watch" avant le début de la transaction.
Ce bug ne se reproduit pas dans mon environnement local, même si j'utilise jmeter pour requêter par lots les API associées, telles que 500 requêtes en 1 seconde
Prédiction : v2.1.2 PHP7.4 Serveur Redis 5.0.10
$redisClient->watch($key); $current = $redisClient->llen($key); // Transaction start $tx = $redisClient->transaction(); if ($current >= $limitNum) { $redisClient->unwatch(); return false; } else { if ($redisClient->exists($key)) { $tx->rpush($key, $now); try { $replies = $tx->execute(); return true; } catch (\Exception $e) { return false; } } else { // Using transaction to let rpush and expire to be an atomic operation $tx->rpush($key, $now); $tx->expire($key, $expiryTime); try { $replies = $tx->execute(); return true; } catch (\Exception $e) { return false; } } }
C'est l'opération attendue sur mon serveur Redis local
Les transactions Redis sont atomiques. Atomique signifie que soit toutes les commandes sont traitées, soit aucune commande n'est traitée. Donc dans mon cas, une clé doit avoir une date d'expiration.
Les transactions Redis ne sont pas de telles transactions atomiques. Ils sont atomiques car aucun autre processus ne peut accéder à l'espace clé pendant l'exécution des transactions de la commande. Si une commande au sein d'une transaction échoue, les commandes suivantes seront exécutées et ne seront pas annulées.
Par exemple, exécutons une transaction qui contient la mauvaise commande :
Ici, nous vérifions si la liste existe et y ajoutons quelques éléments initiaux. Ensuite, au cours de la transaction, nous supprimons un élément de la liste et essayons par erreur d'ajouter un nouvel élément en pensant que la commande clé
mylist
拥有一个集合,然后设置键mylist。第一个和第三个命令成功,最后,
mylist
设置了生存时间。第二个命令失败。为此,Redis 中没有内置回滚功能 - 您的应用程序需要通过watch
utilise le verrouillage optimiste... Il s'agit de détecter les modifications apportées par d'autres processus avant que votre transaction n'obtienne ce qu'elle veut. La clé modifiée a un accès exclusif au serveur. Il ne s'agit pas d'un mécanisme de restauration.Détails : https://redis.io/docs/interact/transactions/