1, Overview
(1) Idempotent definition
1. Idempotent definition in Mathematics
In programming, the characteristic of an idempotent operation is that the impact of any multiple execution is the same as that of one execution. Idempotent functions, or idempotent methods, refer to functions that can be executed repeatedly with the same parameters and obtain the same results. These functions will not affect the system state, and there is no need to worry that repeated execution will change the system. For example, "setTrue()" function is an idempotent function. No matter how many times it is executed, the result is the same The more complex operation idempotent guarantee is realized by using the unique transaction number (serial number).
2. Idempotent definition in programming field
For any number of data changes (> = 0) or only one data change (> = 2) is performed on the same interface. The interface / method / function is considered idempotent
RFC 2616 HTTP idempotency
(2) Why idempotent
The mainstream architecture in the early programming field is monomer architecture, and the calls of interfaces are mostly in-process calls Each interface call has a definite result of failure OR success. With the popularity of distributed architecture, more and more calls are transformed into cross network calls, and the result of calls becomes uncertain due to the stability of the network. In order to avoid the introduction of cumbersome write check coding mode
(3) Scenarios that may produce idempotency
Generally, interfaces are divided into two types (query and modification). For query types, we think that natural idempotence will only affect the data 0 times no matter how many times it is executed. The modification type (add, modify, delete) may have n impacts according to the number of requests
1. Network fluctuation may cause repeated requests
2. The user repeats the operation, and the user triggers multiple requests intentionally or unintentionally
3. The self application uses the retry mechanism (rpc retry or service retry, etc.)
4. The page is refreshed or submitted repeatedly
5. The user double clicks the submit button
2, Project introduction
Project construction tool maven
External structure diagram of the project
Module description
1. Idempotent core: idempotent core dependency package
- The core package mainly provides the implementation of idempotent interception, the creation and destruction of counters, basic configuration, and some interfaces that support the personalized and customized processing of business parties.
- Core class absidempotenauthorizationprocessor
/** * Idempotent processing abstract class * @author gol */ public abstract class AbsIdempotentAuthorizationProcessor implements IdempotentAuthorizationProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(AbsIdempotentAuthorizationProcessor.class); /** * Create idempotent counter * * @param idempotentKey Idempotent key * @param idempotentTime Idempotent time * @param timeUnit temporal strategy * @return boolean */ protected abstract boolean createIdempotentTally(String idempotentKey, Long idempotentTime, TimeUnit timeUnit); /** * Entry to idempotent execution * * @param idempotentKey Idempotent key * @param idempotentTime Idempotent time, default millisecond level * @return boolean */ @Override public boolean execute(String idempotentKey, Long idempotentTime) throws IdempotentException { LOGGER.info("execute idempotent check, idempotentKey:{},idempotentTime:{}", idempotentKey, idempotentTime); return this.execute(idempotentKey, idempotentTime, false); } /** * Entry to idempotent execution * * @param idempotentKey Idempotent key * @param idempotentTime Idempotent time, default millisecond level * @param throwsException Whether to throw an exception * @return boolean */ @Override public boolean execute(String idempotentKey, Long idempotentTime, boolean throwsException) throws IdempotentException { boolean idempotentTally = createIdempotentTally(idempotentKey, idempotentTime, TimeUnit.MILLISECONDS); if (!idempotentTally && throwsException) { throw new IdempotentException(IdempotentConstant.IDEMPOTENT_FAIL_MSG); } return idempotentTally; } /** * @param idempotentKey Idempotent key * @param idempotentTime Idempotent time * @param timeUnit Time policy, default millisecond level * @return boolean * @throws IdempotentException ex */ @Override public boolean execute(String idempotentKey, Long idempotentTime, TimeUnit timeUnit) throws IdempotentException { return this.execute(idempotentKey, idempotentTime, timeUnit, false); } /** * @param idempotentKey Idempotent key * @param idempotentTime Idempotent time * @param timeUnit timeUnit * @param throwsException Whether to throw an exception * @return boolean * @throws IdempotentException IdempotentException */ @Override public boolean execute(String idempotentKey, Long idempotentTime, TimeUnit timeUnit, boolean throwsException) throws IdempotentException { boolean idempotentTally = createIdempotentTally(idempotentKey, idempotentTime, null == timeUnit ? TimeUnit.MILLISECONDS : timeUnit); if (!idempotentTally && throwsException) { throw new IdempotentException(IdempotentConstant.IDEMPOTENT_FAIL_MSG); } return idempotentTally; } }
2. Idempotent reids: idempotent scheme based on redis
redis package mainly realizes idempotent storage, default bean configuration, serialization and so on
3, Instructions for use
1. Import method: maven import
<dependency> <groupId>org.link.redis</groupId> <artifactId>idempotent-redis</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
2. Usage: intercept based on the method
@Autowired private IdempotentComponent idempotentComponent; /** * Idempotent test interface */ @GetMapping("insert/{token}") public void insert(final HttpServletResponse response,@PathVariable String token) throws IOException { PrintWriter writer = response.getWriter(); String key = token; boolean check = idempotentComponent.idempotentCheck(key, 1L,TimeUnit.SECONDS,true); if (!check) { response.setStatus(500); writer.print("insert fail"); log.info("insert fail..."); } else { response.setStatus(200); writer.print("token=" + token + " insert success"); log.info("token=" + token + " insert success"); } writer.close(); }
4, Idempotent detailed method introduction
/** * Idempotent check * * @param idempotentKey Idempotent key * @param idempotentTime Idempotent time, default millisecond level * @return boolean */ public boolean idempotentCheck(String idempotentKey, Long idempotentTime) { return idempotentAuthorizationProcessor.execute(idempotentKey, idempotentTime); } /** * Idempotent check * * @param idempotentKey Idempotent key * @param idempotentTime Idempotent time, default millisecond level * @param throwsException Whether to throw an exception * @return boolean */ public boolean idempotentCheck(String idempotentKey, Long idempotentTime, boolean throwsException) { return idempotentAuthorizationProcessor.execute(idempotentKey, idempotentTime, throwsException); } /** * Idempotent check * * @param idempotentKey Idempotent key * @param idempotentTime Idempotent time * @param timeUnit temporal strategy * @return boolean */ public boolean idempotentCheck(String idempotentKey, Long idempotentTime, TimeUnit timeUnit) { return idempotentAuthorizationProcessor.execute(idempotentKey, idempotentTime, timeUnit); } /** * Idempotent check * * @param idempotentKey Idempotent key * @param idempotentTime Idempotent time * @param timeUnit temporal strategy * @param throwsException Whether to throw an exception * @return boolean */ public boolean idempotentCheck(String idempotentKey, Long idempotentTime, TimeUnit timeUnit, boolean throwsException) { return idempotentAuthorizationProcessor.execute(idempotentKey, idempotentTime, timeUnit, throwsException); }
Source address
Source code: GitHub - imgolye / identotent springboot Star: idempotent component