1.示例场景描述
在项目中,有些接口用于插入数据(如保存或更新操作)。用户在点击保存或更新按钮后,如果未及时收到服务端的响应,可能会多次点击按钮,导致数据库插入多条重复数据。本文将探讨如何使用 Redis 实现接口幂等性校验,以防止这种重复操作的发生。
2.解决方案概述
方案1:前端防抖处理
用户点击按钮后未得到服务端响应时,按钮置灰,防止用户连续点击
方案2:服务端 Redis 锁
使用 Redis 锁,在一次操作未完成时,用户再次点击直接提示用户不能操作。
3.完整代码示例
@Resource
private StringRedisTemplate redisTemplate;
@ApiOperation(value = "卡登记")
@PostMapping("/cardUpdateById")
public CommonResult cardUpdateById(@RequestBody Command commad) {
// 1.生成 Redis 键
String redisKey = String.format(CARD_REGISTER_OPERATE, commad.userId(),commad.getDoctorId());
try {
//2.获取 Redis 键值并校验
String value = redisTemplate.opsForValue().get(redisKey);
if(value!=null) throw new BizException(6000, "当前用户操作正在进行,请稍后重试");
//3.设置 Redis 键值并加锁
redisTemplate.opsForValue().set(redisKey,"1",20, TimeUnit.SECONDS);
//4.调用业务逻辑方法
return CommonResult.withBoolean(smsRegisteredService.cardUpdateById(smsRegisteredUpdateCommand));
}catch (Exception ex){
//5.捕获异常与日志记录
log.error("卡登记报错:{}", ex);
throw ex;
}finally {
//6.删除 Redis 锁
redisTemplate.delete(redisKey);
}
}
4.实际应用中的注意事项
- 设置合理的 Redis 锁过期时间
- 处理 Redis 操作失败的情况
- 高并发环境下的性能优化