redis 判断存在性_SpringBoot + Redis + 注解 + 拦截器 实现接口幂等性校验

点击上方 "程序员小乐"关注, 星标或置顶一起成长

每天凌晨00点00分, 第一时间与你相约

每日英文

Never expect. Never assume. And never demand. Just let it be. If it's meant to be, it will happen.

不要期待,不要假想,不要强求,顺其自然,如果注定,便一定会发生。

每日掏心话

千万不要被胜利冲昏头脑。得意忘形的人,常常会因一时的兴奋而失去理智,看不清眼前的形势和未来的趋势,这样势必会使他不再像以前那样努力,更不会像以前那样稳重。

来自:wangzaiplus | 责编:乐乐

来源:jianshu.com/p/6189275403ed

4de88682208b6f0b7f6f02e4cf1ce52b.png

程序员小乐(ID:study_tech)第 853 次推文 图源:百度

往日回顾:史上最污技术解读,我竟然秒懂了

正文

一、概念

幂等性, 通俗的说就是一个接口, 多次发起同一个请求, 必须保证操作只能执行一次
比如:

  • 订单接口, 不能多次创建订单

  • 支付接口, 重复支付同一笔订单只能扣一次钱

  • 支付宝回调接口, 可能会多次回调, 必须处理重复回调

  • 普通表单提交接口, 因为网络超时等原因多次点击提交, 只能成功一次
    等等

二、常见解决方案

  • 唯一索引 -- 防止新增脏数据

  • token机制 -- 防止页面重复提交

  • 悲观锁 -- 获取数据的时候加锁(锁表或锁行)

  • 乐观锁 -- 基于版本号version实现, 在更新数据那一刻校验数据

  • 分布式锁 -- redis(jedis、redisson)或zookeeper实现

  • 状态机 -- 状态变更, 更新数据时判断状态

三、本文实现

本文采用第2种方式实现, 即通过redis + token机制实现接口幂等性校验

四、实现思路

为需要保证幂等性的每一次请求创建一个唯一标识token, 先获取token, 并将此token存入redis, 请求接口时, 将此token放到header或者作为请求参数请求接口, 后端接口判断redis中是否存在此token:

  • 如果存在, 正常处理业务逻辑, 并从redis中删除此token, 那么, 如果是重复请求, 由于token已被删除, 则不能通过校验, 返回请勿重复操作提示

  • 如果不存在, 说明参数不合法或者是重复请求, 返回提示即可

五、项目简介

  • springboot

  • redis

  • @ApiIdempotent注解 + 拦截器对请求进行拦截

  • @ControllerAdvice全局异常处理

  • 压测工具: jmeter

  • 说明:

  • 本文重点介绍幂等性核心实现, 关于springboot如何集成redis、ServerResponse、ResponseCode等细枝末节不在本文讨论范围之内, 有兴趣的小伙伴可以查看我的Github项目: https://github.com/wangzaiplus/springboot/tree/wxw

六、代码实现

1.pom

  • redis.clientsjedis2.9.0org.projectlomboklombok1.16.10

2.JedisUtil

  • package com.wangzaiplus.test.util;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;@Component@Slf4jpublic class JedisUtil { @Autowired private JedisPool jedisPool; private Jedis getJedis() { return jedisPool.getResource(); } /** * 设值 * * @param key * @param value * @return */ public String set(String key, String value) { Jedis jedis = null; try { jedis = getJedis(); return jedis.set(key, value); } catch (Exception e) { log.error("set key:{} value:{} error

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值