幂等性
- 幂等性是指一个操作在相同的输入下,多次执行的结果是一样的,即不会因为多次点击而产生副作用。在计算机科学中,幂等函数或幂等方法是指可以使用相同参数重复执行,并能获得相同结果的函数。这样的函数不会影响系统状态,也不用担心重复执行会对系统造成改变。
- 在软件系统中,幂等性是一个重要的需求。因为多个用户或者系统可能会同时对同一资源进行操作,所以需要确保这些操作是幂等的,即无论操作执行多少次,结果都是一样的。
- 通俗的将,就是对一个接口执行重复的多次请求,与一次请求所产生的结果是相同的,听起来容易理解,但是要在系统中始终保持这个目标,是需要很严谨的设计的。
需要进行幂等处理的请求
- 首先,查询类的请求一般都是幂等的,删除请求在大多数情况下也是幂等的。
- 举个例子比如,先请求了一次删除A的操作,但由于响应超时,又自动请求了一次删除A的操作,如果在两次请求之间,又插入了一次A,而实际上新插入的这一次A,是不应该被删除的,这种情况就需要处理了,不过,在大多数业务场景中,这种问题基本上可以忽略。
- 除了查询和删除之外,还有更新操作,同样的更新操作在大多数场景下也是幂等的,其例外是也会存在一些场景会有非幂等问题,比如执行update table_name set a = a + 1 where b = 1这样的更新就非幂等了。
- 最后,还剩新增,新增大多数情况下都是非幂等的,或者也可以利用数据库唯一索引来保证数据不会重复产生。
需要幂等的一些业务场景
- 超时重试
- 当发起一次请求时,可能会因为网络不稳定而导致请求失败,一般遇到这样的问题我们希望能够重新请求一次,正常情况下没有问题,但有时请求实际上已经发出去了,只是在请求响应时网络异常或者超时,此时,请求方如果再重新发起一次请求,那被请求方就需要保证幂等。特别是金钱支付或积分等资源的操作以及库存的管理等。
- 异步消息
- 现在的消息框架很多都允许重复消息,既然消息队列保证不了不会出现重复的消息,消费者自然要保证处理逻辑的幂等性。
- 需要进行唯一性检查的场景
- 例如,在用户注册时,需要保证用户名或邮箱的唯一性。如果多个用户同时注册相同的信息,系统需要保证只创建一个用户,避免重复用户的出现。
实现幂等的思路
- 幂等的唯一标识,也可以说是幂等令牌或者全局ID,就是客户端与服务端一次请求时的唯一标识,由客户端或服务端生成都可以,也可以让第三方来统一分配。
- 可以一个请求生成一个唯一ID,请求时带上唯一ID,以此ID来判断此请求是否已经请求过。
- 也可以根据请求参数生成一个请求token,可以使用AOP或者注解实现,对某些请求或者某个包下的接口业务进行幂等处理,也可以增加上时间和登录人等属性来判断请求是否已经完成。
- 使用数据库唯一主键实现幂等性:利用数据库中主键唯一约束的特性,确保一张表中只能存在一条带该唯一主键的记录。这种方法主要适用于“插入”时的幂等性,需要注意在分布式环境下确保 ID 的全局唯一性。
- 先查询再插入:对于支持重复执行的后台系统或任务,可以先查询一些关键数据,判断是否已经执行过,再进行业务处理。这种方法适用于并发度不高的场景。