针对防止四级登录时表单重复提交的问题,可以采取以下综合解决方案:
一、后端防重提交的核心方法
-
Token机制
-
生成唯一Token(如UUID),前端提交时附带该Token;
-
后端验证Token唯一性后立即失效,防止重复处理。
-
-
分布式锁
- 使用Redis或Zookeeper实现分布式锁,确保同一时间只有一个请求能执行关键操作。
-
数据库唯一约束
- 在数据库关键字段(如订单号、用户ID)添加唯一约束,避免重复记录。
-
事务管理
- 使用数据库事务(如MySQL的隔离级别)确保操作原子性,部分场景可结合乐观锁机制。
二、具体实现方案
1. 使用Token机制(推荐)
-
后端实现 :在用户登录时生成唯一Token,存储在Session或数据库中,表单提交时验证Token。
-
示例代码 (Spring Boot):
@PostMapping("/login") public ResponseEntity<?> login(@RequestParam String username, @RequestParam String password, @SessionAttribute("loginToken") String token) { if (!token.equals(generateToken(username))) { return ResponseEntity.badRequest().body("Invalid token"); } // 验证用户名密码逻辑 // ... return ResponseEntity.ok("Login successful"); } private String generateToken(String username) { return UUID.randomUUID().toString(); }
-
前端实现 :表单提交时在隐藏字段中添加Token。
2. 分布式锁方案(适用于高并发)
-
使用Redis实现 :通过
SETNX
命令获取锁,操作完成后释放。 -
示例代码 (Spring Boot):
@Autowired private RedisTemplate<String, String> redisTemplate; public boolean acquireLock(String lockKey, String requestId, int expireTime) { Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, expireTime, TimeUnit.SECONDS); return result != null && result; } public void releaseLock(String lockKey, String requestId) { redisTemplate.delete(lockKey); }
-
拦截器实现 :在Controller方法执行前检查锁,成功获取后执行业务逻辑。
3. 数据库唯一约束
-
在数据库表中为关键字段添加唯一约束(如用户ID+操作类型)。
-
示例SQL:
ALTER TABLE user_operations ADD CONSTRAINT unique_operation UNIQUE (user_id, operation_type)
。