其实在单体服务时代,也会有接口幂等性的问题,只是在分布式、高并发的场景下,接口幂等性的问题会更加明显一些。那么什么是幂等性?当用户对同一操作请求了一次或者多次,最终的结果
其实在单体服务时代,也会有接口幂等性的问题,只是在分布式、高并发的场景下,接口幂等性的问题会更加明显一些。那么什么是幂等性?当用户对同一操作请求了一次或者多次,最终的结果是一致的,并不会因为多次请求产生副作用;比如同一个订单支付了两次,最后应该只扣客户一次钱。
查询接口具有天然的幂等性(查询一次还是多次,结果应该都是一样的),但是在做新增、修改、删除操作的时候,都要保证幂等性。
全局唯一ID
每一次的请求,都有一个全局唯一的请求ID,这个请求ID只要执行过一次就失效了:
获得请求ID。
调用接口,同时传递请求ID。
交易前判断请求ID是否存在,如果存在直接返回结果;如果不存在,则执行交易后返回结果,同时记录请求ID。
许多微服务的架构,生产全局唯一ID都被作为一个基础的微服务,当然这个微服务的可靠性要求极高,因为这个微服务出现问题,可能会导致很多服务不能工作;所以通常分布式的架构中,会引入全局唯一ID算法。
数据版本号
这种方法适合在更新的场景中,数据中增加版本号的概念,那么在做数据修改,把当前数据的版本号带上,修改的时候要按照版本号判断数据是否发生过更改。如果没有发生过更改,则执行业务操作,并更新版本号。下面的代码,意会一下:
updateDate(Object obj , int version);
update set obj , version+1 where ...version = 入参version;
状态机
有些业务流程,每一步都是有状态的,比如网上购物可能会有:订单创建、付款、发货,那么付款之前保单状态为“待付款”,付款之后可以将保单的状态修改为“待发货”;那么如果发起重复扣款的话,第二次扣款的时候保单状态已经变化了,就会扣款失败。
去重表
如果业务中有唯一性的标识时,可以使用去重表,把这个唯一性的表示保存到去重表中,如果重复插入,那么会被校验住。
比如上面的场景,一个订单只会付款一次,那么在付款的时候,把订单号作为唯一性的标识,保存到去重表中,可以保证付款操作只会发生一次。
我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注。