场景
幂等性的使用的场景是为了避免一个动作重复提交,可能会造成数据不准确。本文使用redis来实现幂等性功能。
小场景流程图:
maven依赖
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
demo
/**
* 幂等性
*/
public class Idempotent {
private static Jedis jedis;
private static final String LUASCRIPT = "if redis.call('get', KEYS[1]) == nil then return 0 else return redis.call('del', KEYS[1]) end";
private static final String IDEMPOTENT_KEY = "idempotent_";
public static void main(String[] args) {
jedis = new Jedis("121.4.39.102",6379);
//生成订单token
String token = createToken();
//再请求支付,避免重复支付
checkToken(token);
}
private static void checkToken(String token) {
try {
//需要保持原子性。所以用到了lua脚本去执行
long result = (long) jedis.eval(LUASCRIPT, Arrays.asList(IDEMPOTENT_KEY+token),new ArrayList<>());
if (result == 1){//执行业务
System.out.println("开始执行业务");
}
} catch (Exception e) {
//出现异常必须将缓存设置回来
jedis.setex(IDEMPOTENT_KEY+token,2 * 60,"1");
System.out.println(e.getMessage());
}
}
private static String createToken() {
String token = UUID.randomUUID().toString();
jedis.setex(IDEMPOTENT_KEY+token,15 * 60,"1");
return token;
}
}