1. Concept : L'impact de toute exécution multiple est le même que l'impact d'une seule exécution.
Selon ce sens, le sens final est que l'impact sur la base de données ne peut être qu'une seule fois et ne peut pas être traité de manière répétée. Comment garantir son idempotence, les méthodes suivantes sont généralement utilisées :
1 : La base de données établit un index unique, qui peut garantir qu'une seule donnée est finalement insérée dans la base de données
2 : Mécanisme de jeton, obtenez un jeton avant chaque demande d'interface, puis la prochaine fois que vous demanderez, ajoutez ce jeton au corps d'en-tête de la demande et vérifiez-le en arrière-plan, supprimez le jeton et jugez-le à nouveau pour la prochaine demande
. 3 : Verrouillage pessimiste ou verrouillage optimiste, le verrouillage pessimiste peut garantir que chaque mise à jour est effectuée. Lorsqu'un autre SQL ne peut pas mettre à jour les données (lorsque le moteur de base de données est innodb, la condition de sélection doit être un index unique pour éviter de verrouiller la table entière)
4 : Interrogez d'abord, puis jugez. Tout d'abord, interrogez la base de données pour voir si les données existent. Si elles existent, il est prouvé qu'elles l'ont été. Si la demande a été acceptée, la demande sera directement rejetée. prouve que c'est la première fois que vous entrez et que la demande sera libérée directement.
Redis réalise le schéma de principe de l'idempotence automatique :
1 : Tout d'abord, construisez le serveur redis.
2 : Introduisez le stater redis dans springboot, ou le jedis encapsulé par Spring. L'API principale utilisée plus tard est sa méthode set et exist. Ici, nous utilisons le redisTemplate encapsulé de springboot
Le code est le suivant :
/* redis工具类 */ @Component public class RedisService { @Autowired private RedisTemplate redisTemplate; /** * 写入缓存 * @param key * @param value * @return */ public boolean set(final String key,Object value){ boolean result = false; try { ValueOperations<Serializable,Object> operations = redisTemplate.opsForValue(); operations.set(key,value); result = true; }catch (Exception e){ result = false; e.printStackTrace(); } return result; } /** * 写入缓存有效期 * @return */ public boolean setEx(final String key ,Object value,Long expireTime){ boolean result = false; try { ValueOperations<Serializable,Object> operations = redisTemplate.opsForValue(); operations.set(key,value); redisTemplate.expire(key,expireTime, TimeUnit.SECONDS);//有效期 result = true; }catch (Exception e){ result = false; e.printStackTrace(); } return result; } /** * 判断缓存中是否有对应的value * @param key * @return */ public boolean exists(final String key){ return redisTemplate.hasKey(key); } /** * 读取缓存 * @param key * @return */ public Object get(final String key){ Object obj = null; ValueOperations<Serializable,Object> operations= redisTemplate.opsForValue(); obj = operations.get(key); return obj; } /** * 删除对应的value * @param key * @return */ public boolean remvoe(final String key){ if(exists(key)){ Boolean delete = redisTemplate.delete(key); return delete; } return false; } }
Personnalisez une annotation. Le but principal de la définition de cette annotation est de l'ajouter aux méthodes qui doivent être idempotentes. Chaque fois qu'une méthode l'annote, elle réalisera une idempotence automatique. Si cette annotation est analysée en utilisant la réflexion en arrière-plan, elle traitera cette méthode pour obtenir une idempotence automatique. Utilisez la méta-annotation ElementType.METHOD pour indiquer qu'elle ne peut être placée que sur la méthode, et etentionPolicy.RUNTIME pour indiquer qu'elle l'est. au moment de l'exécution
package com.yxkj.springboot_redis_interceptor.annotion; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface AutoIdempotent { }
Nous créons une nouvelle interface pour créer un service de jeton. Elle contient principalement deux méthodes, l'une est utilisée pour créer le jeton et l'autre. utilisé pour vérifier le jeton. La création d'un jeton génère principalement une chaîne lors de la vérification du jeton, elle transmet principalement l'objet de requête. Pourquoi devons-nous transmettre l'objet de requête ? La fonction principale est d'obtenir le jeton dans l'en-tête, puis de le vérifier, d'obtenir les informations d'erreur spécifiques via l'exception levée et de les renvoyer au front-end
public interface TokenService { /** * 创建token * @return */ String createToken(); /** * 检验token的合法性 * @param request * @return * @throws Exception */ boolean checkToken(HttpServletRequest request) throws Exception; }
le jeton fait référence au service redis , et utilise des outils d'algorithmes aléatoires pour créer le jeton. La classe génère une chaîne uuid aléatoire puis la place dans Redis (afin d'éviter une rétention redondante des données, le délai d'expiration est fixé à 10 000 secondes, ce qui dépend de l'entreprise). le put est réussi, la valeur du jeton est finalement renvoyée. La méthode checkToken consiste à obtenir le jeton de l'en-tête vers la valeur (s'il ne peut pas être obtenu à partir de l'en-tête, récupérez-le à partir du paramètre. S'il n'existe pas, il lancera directement une exception). Ces informations d'exception peuvent être interceptées par l'intercepteur puis renvoyées au frontal.
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!