Les commandes de verrouillage courantes de redis sont INCR, SETNX, SET
L'idée de verrouillage dece type de verrou est la suivante :
la clé n'existe pas, alors la valeur de la clé sera être initialisé à 0 d'abord, puis effectuez ensuite l'opération INCR pour en ajouter un.
Ensuite, lorsque d'autres utilisateurs effectuent l'opération INCR pour en ajouter une, si la valeur renvoyée est supérieure à 1, cela signifie que la clé est verrouillée pour utilisation.
1. Le client A demande au serveur d'obtenir la clé d'une valeur de 1, indiquant que le verrou a été obtenu.
2. Le client B demande également au serveur d'obtenir la clé d'une valeur de 2, indiquant que le L'acquisition du verrou a échoué.
3. Le client A termine l'exécution du code, supprimez le verrou
4 Après avoir attendu un certain temps, le client B obtient la valeur de clé de 1 lors de la demande, indiquant que le verrou a été obtenu avec succès
. 5. Le client B termine l'exécution du code et supprime le verrou
$redis->incr($key); $redis->expire($key, $ttl); //设置生成时间为1秒
Commande spécifique :
127.0.0.1:6379>INCR keyName
L'idée de ce type de verrouillage est que si la clé n'existe pas, définissez la clé sur valeur. Si la clé existe, SETNX n'effectue aucune action.
SETNX est l'abréviation de SET if Not eXists.
1. Le client A demande au serveur de définir la valeur de la clé. Si le paramètre est réussi, cela signifie que le verrouillage est réussi.
2. Le client B demande également au serveur de définir la valeur de la clé. cela signifie que le verrouillage échoue.
3. Le client A termine l'exécution du code et supprime le verrou
4 Le client B demande de définir la valeur de la clé après un certain temps d'attente, et le réglage est réussi
5. . Le client B termine l'exécution du code et supprime le verrou
$redis->setNX($key, $value); $redis->expire($key, $ttl);
Commandes spécifiques à utiliser :
redis> SETNX keyName value (integer) 1
Si le réglage est réussi, 1 sera renvoyé si le réglage échoue, 0 sera renvoyé.
Si l'exécution de la requête se termine de manière inattendue pour une raison quelconque, provoquant la création mais pas la suppression du verrou, alors le verrou existera toujours, de sorte que le cache ne sera jamais mis à jour à l'avenir.
Nous devons donc ajouter un délai d'expiration au verrou pour éviter des événements inattendus.
Mais le définir avec Expire n'est pas une opération atomique.
Vous pouvez donc également garantir l'atomicité via les transactions, mais il y a encore quelques problèmes, c'est pourquoi le responsable en a cité un autre. L'utilisation de la commande SET elle-même a inclus la fonction de réglage du délai d'expiration à partir de la version 2.6.12.
1. Le client A demande au serveur de définir la valeur de la clé. Si le paramètre est réussi, cela signifie que le verrouillage est réussi.
2. Le client B demande également au serveur de définir la valeur de la clé. signifie que le verrouillage a échoué.
3. Le client A termine l'exécution du code et supprime le verrou
4. Le client B demande de définir la valeur de la clé après un certain temps d'attente. Le client B termine l'exécution du code et supprime le verrou
$redis->set($key, $value, array('nx', 'ex' => $ttl)); //ex表示秒
Utilisation spécifique :
redis>set key value NX EX max-lock-time 实现加锁
Explication de la commande :
key
: key est la valeur clé de redis comme identification du verrou , et la valeur est utilisée ici comme identification du client. Seule la correspondance clé-valeur peut être supprimée. Le droit de verrouiller [garantir la sécurité]
max-lock-time
: définir l'expiration. temps jusqu'à max-lock-time pour garantir qu'aucun blocage ne se produira [éviter les blocages] key
:key就是redis的key值作为锁的标识,value在这里作为客户端的标识,只有key-value都比配才有删除锁的权利【保证安全性】
max-lock-time
:通过max-lock-time设置过期时间保证不会出现死锁【避免死锁】
NX
:只有这个key不存才的时候才会进行操作,if not exists;
EX
;
EX
: Réglez le délai d'expiration de la clé sur quelques secondes, le temps spécifique est déterminé par 5 paramètres déterminer Code de verrouillage :
Jedis jedis = new Jedis("127.0.0.1", 6379); private static final String SUCCESS = "OK"; /** * 加锁操作 * @param key 锁标识 * @param value 客户端标识 * @param timeOut 过期时间 */ public Boolean lock(String key,String value,Long timeOut){ String var1 = jedis.set(key,value,"NX","EX",timeOut); if(LOCK_SUCCESS.equals(var1)){ return true; } return false; }
Code de déverrouillage :
🎜Jedis jedis = new Jedis("127.0.0.1", 6379); private static final Long UNLOCK_SUCCESS = 1L; /** * 解锁操作 * @param key 锁标识 * @param value 客户端标识 * @return */ public static Boolean unLock(String key,String value){ String luaScript = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then return redis.call(\"del\",KEYS[1]) else return 0 end"; Object var2 = jedis.eval(luaScript,Collections.singletonList(key), Collections.singletonList(value)); if (UNLOCK_SUCCESS == var2) { return true; } return false; }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!