接口的幂等设计

Posted java微分享

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了接口的幂等设计相关的知识,希望对你有一定的参考价值。

1.背景

最近的系统中使用了springCloud微服务框架,这种分布式框架的确提供了非常多便利的地方,不过随之也出现了很多的问题,特别是在实际开发中,接口的幂等性。

而所谓的幂等,通俗点说就是一个操作不管请求多少次返回的结果都是一样的,比如支付、扣除库存、扣除积分等等,如果因为网络问题而出现多扣、多加、多新增数据的问题,

不仅会影响用户体验,数据的维护也非常的困难。


2.概念

幂等:在编程中一个幂等操作中任意多次执行产生的影响均与一次执行的影响相同。幂等函数或者方法,是指可以使用相参数重复执行,并能获取相同结果的函数。这些函数不会影响系统状态。


3.具体实现

a)、增加唯一索引

就比如一个用户签到赠送积分的场景,用户进入程序的首页就触发签到程序,主动给用户签到,并且赠送积分。但是由于网络的问题,前端同一个用户的签到触发了两次请求,积分也赠送了两次。

程序的初始也做了一些基本的重复签到处理,如select + insert,查询某用户是否签到过,然后再进行签到。虽然能简单有效的控制重复签到的问题,但是高并发的情况下,而且是在分布式框架中,select + insert 就显得非常的无力。那么唯一索引就非常好的解决了这个问题。设计签到表时,把用户的ID和签到日期作为表的联合唯一主键,这样签到表中无论什么情况下只可能存在一条签到数据,积分也可能赠送一次。


b)、乐观锁版本控制

这种方法适合在更新的场景中,比如我们要更新商品的名字,这时我们就可以在更新的接口中增加一个版本号,来做幂等:

update goods set name=#{newName},version=#{version} where id=#{id} and version<${version}


c)、token机制,前端防止重复提交

数据提交前向服务器申请token,token放到redis中,提交后后台校验token,同时删除tonken,保证了每个请求只有一个tonken。

不过要注意的点是,这种方式通过删除token结果来校验token的正确性。

如果删除前加了查询(select)再删除来校验token,那么又会引发并发问题,存在隐患。


d)、状态机控制

    这种方法适合在有状态机流转的情况下,比如就会订单的创建和付款,订单的付款肯定是在之前,这时我们可以通过在设计状态字段时,使用int类型,并且通过值类型的大小来做幂等,比如订单的创建为0,付款成功为100。付款失败为99

update `order` set status=#{status} where id=#{id} and status<#{status}


e)、去重表

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

全套架构视频教程免费分享




以上是关于接口的幂等设计的主要内容,如果未能解决你的问题,请参考以下文章

浅谈常用接口中的幂等设计

分布式接口的幂等性设计

分布式服务的幂等性设计

接口服务中的幂等性设计和防重保证,详细分析幂等性设计几种实现方法

阿里面试官:接口的幂等性怎么设计?

理解http的幂等性