接口幂等性

概念

幂等性:就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击(调用)而产生了副作用。即幂等性=多次执行结果一致+无副作用,查询(select)方法本身就是幂等性的,虽然多次执行可能返回结果不一致,但是没有任何副作用。插入(insert)和修改(update)方法是非幂等性的,需要通过机制在需要的场景处理以确保多次执行无副作用。删除(delete)执行一次或多次都是结果为空(即结果一致),并且无副作用,所以在根据主键ID删除可以认为是(伪)幂等性的,根据非主键删除的如果多次执行无副作用(都是把数据删除),也可以认为是(伪)幂等性。

幂等性是系统的接口对外一种承诺(而不是实现), 承诺只要调用接口成功, 外部多次调用对系统的影响是一致的。幂等性是分布式系统设计中的一个重要概念,对超时处理、系统恢复等具有重要意义。声明为幂等的接口会认为外部调用失败是常态, 并且失败之后必然会有重试。

幂等性保障方案

1、全局唯一ID

如果使用全局唯一ID,就是根据业务的操作(业务类型)和内容生成一个全局ID,在执行操作前先根据这个全局唯一ID是否存在,来判断这个操作是否已经执行。如果不存在则把全局ID,存储到存储系统中,比如数据库、redis等。如果存在则表示该方法已经执行,这个全局ID有时效性。

从工程的角度来说,使用全局ID做幂等可以作为一个业务的基础的微服务存在,在很多的微服务中都会用到这样的服务,在每个微服务中都完成这样的功能,会存在工作量重复。另外打造一个高可靠的幂等服务还需要考虑很多问题,比如一台机器虽然把全局ID先写入了存储,但是在写入之后挂了,这就需要引入全局ID的超时机制。

扫描二维码关注公众号,回复: 425953 查看本文章

思路上类似于防止表单重复提交中的token机制,在数据提交前要向服务的申请token,token放到redis或jvm内存,token有效时间,提交后后台校验token,同时删除token,生成新的token返回。token特点:要申请,一次有效性,可以限流 

适用场景:插入、更新、删除

2、去重表+唯一索引

这种方法适用于在业务中有唯一标识的插入场景中,比如在以上的支付场景中,如果一个订单只会支付一次,所以订单ID可以作为唯一标识。这时,我们就可以建一张去重表,并且把唯一标识作为唯一索引,在我们实现时,把创建支付单据和写入去去重表,放在一个事务中,如果重复创建,数据库会抛出唯一约束异常,操作就会回滚。

本地事务+本地库中同一结构的去重表,缺点每个业务库都要维护一张去重表。我觉得也可以通过增加唯一约束,针对部分具有唯一性的业务字段来达到目的。但是这两种做法在业务库集群部署的场景下,也存在问题,可以考虑进入分布式锁来解决。

适用场景:插入,在插入业务前一般先执行select

3、版本号或状态码

版本号类似于乐观锁(悲观锁也可以实现不推荐),每次修改时带上作为where条件。状态码适用于带有流程走向的业务场景,比如订单流程,每次修改时带上作为where条件。其实,多个其他业务字段都可以根据需要,在修改时作为where条件。

多版本并发控制,该策略主要使用update with condition(更新带条件来防止)来保证多次外部请求调用对系统的影响是一致的。在系统设计的过程中,合理的使用乐观锁,通过version或者updateTime(timestamp)等其他条件,来做乐观锁的判断条件,这样保证更新操作即使在并发的情况下,也不会有太大的问题。

适用场景:修改

猜你喜欢

转载自hengdu.iteye.com/blog/2419795