Java面试,接口幂等
时间: 2025-07-07 12:52:21 AIGC 浏览: 21
### Java 面试中接口幂等性的概念与实现方式
#### 一、接口幂等性的定义
接口幂等性是指同一个请求无论被提交多少次,其产生的效果都是一致的。换句话说,即使客户端因网络或其他原因多次发送相同的请求,服务器端也只会将其视为一次操作处理[^4]。
---
#### 二、常见的场景分析
1. **重复提交表单**
用户可能由于页面未及时响应等原因连续点击按钮,导致同一份数据被多次提交。
2. **失败重试机制**
对于一些依赖外部系统的接口调用,在发生超时或断网的情况下可能会触发自动重试逻辑,从而引发重复调用问题[^2]。
3. **消息队列中的重复消费**
在分布式系统中,消息中间件可能存在重复投递的现象,这也会带来幂等问题[^3]。
---
#### 三、实现方式详解
以下是几种常用的实现方法:
##### 方法一:基于唯一标识符(Token)
通过生成全局唯一的 Token 来标记每一次请求,并存储到缓存或者数据库中。当接收到新的请求时,先验证该 Token 是否已存在;如果不存在,则继续业务流程并记录下来;反之则拒绝此次请求。
```java
// 定义注解用于标注需要进行幂等校验的方法
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotRepeat {
String tokenKey() default "token";
}
// AOP切面拦截器
@Component
@Aspect
public class IdempotentInterceptor {
private static final long EXPIRE_TIME = 60L; // 缓存过期时间 单位秒
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Around("@annotation(notRepeat)")
public Object around(ProceedingJoinPoint joinPoint, NotRepeat notRepeat) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String token = request.getParameter(notRepeat.tokenKey());
if (StringUtils.isEmpty(token)) {
throw new RuntimeException("缺少参数:" + notRepeat.tokenKey());
}
Boolean exists = redisTemplate.opsForValue().setIfAbsent(token, "", Duration.ofSeconds(EXPIRE_TIME));
if (!exists) {
throw new RuntimeException("请勿重复提交!");
}
try {
return joinPoint.proceed(); // 执行目标方法
} finally {
redisTemplate.delete(token); // 清理资源
}
}
}
```
此方法适用于大多数场景下的防重复提交需求[^1]。
---
##### 方法二:数据库乐观锁
利用版本号字段 `version` 或者更新条件来控制并发修改行为。每次更新前都会检查当前记录的状态是否满足预期值,如果不匹配就抛出异常终止事务。
假设有一个订单表 Orders(id,name,status,create_time), 我们可以这样写 SQL:
```sql
UPDATE orders SET status='PAID', version=version+1 WHERE id=? AND version=?
```
只有当查询出来的旧版号等于传入的新版号减一时才会成功生效一条记录,否则说明已经有其他线程抢先一步完成了更改动作。
---
##### 方法三:补偿型设计模式
针对某些无法直接做到完全意义上的幂等的操作,可以通过事后修复的方式来弥补错误后果。例如转账类功能,可以在接收方账户余额增加的同时减少付款方金额;一旦发现某笔交易出现了多余扣款情况,立即启动回滚程序恢复原状[^4]。
---
##### 方法四:幂等队列
引入专门的消息去重组件,比如 Kafka 的 Exactly Once Semantics 特性能够很好地支持这一特性。生产者负责向主题推送事件流之前附加额外的时间戳属性作为依据判断是否存在历史副本实例尚未完成最终确认阶段即可忽略掉后续到来相同内容的数据包[^2]。
---
### 总结
以上介绍了四种主流的技术手段应对实际开发过程中遇到的各种复杂状况下保持一致性原则的要求。具体采用哪种策略取决于项目背景以及性能考量等因素综合权衡决定最佳实践方案[^4]。
阅读全文
相关推荐



















