接口的幂等性实际上就是接口可重复调用,在调用方屡次调用的状况下,接口最终获得的结果是一致的。有些接口能够自然的实现幂等性,好比查询接口,对于查询来讲,查询一次和两次,对于系统来讲,没有任何影响,查出的结果也是同样。
除了查询功能具备自然的幂等性以外,增长、更新、删除都要保证幂等性。那么如何来保证幂等性呢?mysql
若是使用全局惟一ID,就是根据业务的操做和内容生成一个全局ID,在执行操做前先根据这个全局惟一ID是否存在,来判断这个操做是否已经执行。若是不存在则把全局ID,存储到存储系统中,好比数据库、redis等。若是存在则表示该方法已经执行。redis
从工程的角度来讲,使用全局ID作幂等能够做为一个业务的基础的微服务存在,在不少的微服务中都会用到这样的服务,在每一个微服务中都完成这样的功能,会存在工做量重复。另外打造一个高可靠的幂等服务还须要考虑不少问题,好比一台机器虽然把全局ID先写入了存储,可是在写入以后挂了,这就须要引入全局ID的超时机制。sql
使用主键冲突的策略进行防重,在并发量很是高的状况下对数据库性能会有影响,尤为是应用数据表和主键冲突表在一个库的时候,表现更加明显。其实针对是否会对数据库性能产生影响这个话题,我也和一些专业的DBA同窗讨论过,广泛承认的是在MySQL数据库中采用主键冲突防重,在大并发状况下有可能会形成锁表现象,比较好的办法是在程序中生产主键进行防重。数据库
这种方法适用于在业务中有惟一标的插入场景中,好比在以上的支付场景中,若是一个订单只会支付一次,因此订单ID能够做为惟一标识。这时,咱们就能够建一张去重表,而且把惟一标识做为惟一索引,在咱们实现时,把建立支付单据和写入去去重表,放在一个事务中,若是重复建立,数据库会抛出惟一约束异常,操做就会回滚。并发
这种方法插入而且有惟一索引的状况,好比咱们要关联商品品类,其中商品的ID和品类的ID能够构成惟一索引,而且在数据表中也增长了惟一索引。这时就可使用InsertOrUpdate操做。微服务
这种方法适合在更新的场景中,好比咱们要更新商品的名字,这时咱们就能够在更新的接口中增长一个版本号,来作幂等性。惟一的问题就是对数据表侵入较大,要为每一个表设计一个版本号字段,而后写一条判断sql每次进行判断。性能
这种方法适合在有状态机流转的状况下,好比就会订单的建立和付款,订单的付款确定是在以前,这时咱们能够经过在设计状态字段时,使用int类型,而且经过值类型的大小来作幂等,好比订单的建立为0,付款成功为100。付款失败为99spa