一、什么是幂等性
所谓幂等,简单地说,就是对接口的多次调用所产生的结果和调用一次是一致的。
那么我们为什么需要接口具有幂等性呢?设想一下以下情形:
- 支付接口,重复支付会导致多次扣钱 订单接口,同一个订单可能会多次创建。
- 在接收消息的时候,消息推送重复。如果处理消息的接口无法保证幂等,那么重复消费消息产生的影响可能会非常大。
二、幂等性的解决方案
(1)唯一索引
使用唯一索引可以避免脏数据的添加,当插入重复数据时数据库会抛异常,保证了数据的唯一性。
(2)乐观锁
这里的乐观锁指的是用乐观锁的原理去实现,为数据字段增加一个version字段,当数据需要更新时,先去数据库里获取此时的version版本号
select version from tablename where xxx
更新数据时首先和版本号作对比,如果不相等说明已经有其他的请求去更新数据了,提示更新失败。
update tablename set count=count+1,version=version+1 where version=#{version}
(3)悲观锁
乐观锁可以实现的往往用悲观锁也能实现,在获取数据时进行加锁,当同时有多个重复请求时其他请求都无法进行操作
(4)分布式锁
幂等的本质是分布式锁的问题,分布式锁正常可以通过redis或zookeeper实现;在分布式环境下,锁定全局唯一资源,使请求串行化,实际表现为互斥锁,防止重复,解决幂等。
目前主要有三种方式实现redis的分布式锁:
- setNx 命令
- set 命令
- Redission 框架
具体流程图如下:

具体步骤:
- 用户通过浏览器发起请求,服务端会收集数据,并且生成订单号 code 作为唯一业务字段。
- 使用 redis 的 set 命令,将该订单 code 设置到 redis 中,同时设置超时时间。
- 判断是否设置成功,如果设置成功,说明是第一次请求,则进行数据操作。
- 如果设置失败,说明是重复请求,则直接返回成功。
需要特别注意的是:分布式锁一定要设置一个合理的过期时间,如果设置过短,无法有效的防止重复请求。如果设置过长,可能会浪费redis的存储空间,需要根据实际业务情况而定。
(5)token机制
token 机制的核心思想是为每一次操作生成一个唯一性的凭证,也就是 token。一个 token 在操作的每一个阶段只有一次执行权,一旦执行成功则保存执行结果。对重复的请求,返回同一个结果。token 机制的应用十分广泛。
该方案跟之前的所有方案都有点不一样,需要两次请求才能完成一次业务操作。
- 第一次请求获取
token - 第二次请求带着这个
token,完成业务操作。
具体流程图如下:
第一步,先获取token。

第二步,做具体业务操作。

具体步骤:
- 用户访问页面时,浏览器自动发起获取token请求。
- 服务端生成token,保存到redis中,然后返回给浏览器。
- 用户通过浏览器发起请求时,携带该token。
- 在redis中查询该token是否存在,如果不存在,说明是第一次请求,做则后续的数据操作。
- 如果存在,说明是重复请求,则直接返回成功。
- 在redis中token会在过期时间之后,被自动删除。
以上方案是针对幂等设计的。
如果是防重设计,流程图要改改:

需要特别注意的是:token必须是全局唯一的。
接口幂等性是确保多次请求同一接口不会导致额外副作用的重要特性。本文详细介绍了幂等性的概念,阐述了为何在支付、订单创建等场景中需要保证幂等性。接着,提出了五种实现幂等性的解决方案:唯一索引、乐观锁、悲观锁、分布式锁和token机制,并结合具体业务场景进行了详细解释。分布式锁的实现中特别强调了设置合理过期时间的重要性,而token机制则需要两次请求来完成业务操作,以确保幂等性。这些方法在防止重复操作和保障系统稳定性方面具有关键作用。
161

被折叠的 条评论
为什么被折叠?



