针对客户端连续点击或者调用方的超时重试等情况,例如提交订单,此种操作就可以用 Token
的机制实现防止重复提交。
简单的说就是调用方在调用接口的时候先向后端请求一个全局 ID(Token)
,请求的时候携带这个全局 ID
一起请求(Token
最好将其放到 Headers
中),后端需要对这个 Token
作为 Key
,用户信息作为 Value
到 Redis
中进行键值内容校验,如果 Key
存在且 Value
匹配就执行删除命令,然后正常执行后面的业务逻辑。如果不存在对应的 Key
或 Value
不匹配就返回重复执行的错误信息,这样来保证幂等操作。
适用操作
- 插入操作
- 更新操作
- 删除操作
使用限制
- 需要生成全局唯一
Token
串 - 需要使用第三方组件
Redis
进行数据效验
主要流程:
- 服务端提供获取 Token 的接口,该 Token 可以是一个序列号,也可以是一个分布式
ID
或者UUID
串。 - 客户端调用接口获取 Token,这时候服务端会生成一个 Token 串。
- 然后将该串存入 Redis 数据库中,以该 Token 作为 Redis 的键(注意设置过期时间)。
- 将 Token 返回到客户端,客户端拿到后应存到表单隐藏域中。
- 客户端在执行提交表单时,把 Token 存入到
Headers
中,执行业务请求带上该Headers
。 - 服务端接收到请求后从
Headers
中拿到 Token,然后根据 Token 到 Redis 中查找该key
是否存在。 - 服务端根据 Redis 中是否存该
key
进行判断,如果存在就将该key
删除,然后正常执行业务逻辑。如果不存在就抛异常,返回重复提交的错误信息。
“ 注意,在并发情况下,执行 Redis 查找数据与删除需要保证原子性,否则很可能在并发下无法保证幂等性。其实现方法可以使用分布式锁或者使用 Lua
表达式来注销查询与删除操作。