什么是幂等性
一个接口被重复调用,对系统的影响是一致的。无论是一次还是多次,数据是一致的,效果也一样。
什么情况下需要幂等
SELECT col1 FROM tab1 WHER col2=2,无论执行多少次都不会改变状态,是天然的幂等。
UPDATE tab1 SET col1=1 WHERE col2=2,无论执行成功多少次状态都是一致的,因此也是幂等操作。
UPDATE tab1 SET col1=col1+1 WHERE col2=2,每次执行的结果都会发生变化,这种不是幂等的。
insert into user(userid,name) values(1,‘a’) 如userid为唯一主键,即重复操作上面的业务,只会插入一条用户数据,具备幂等性。
如userid不是主键,可以重复,那上面业务多次操作,数据都会新增多条,不具备幂等性。
delete from user where userid=1,多次操作,结果一样,具备幂等性
如何保证幂等
唯一主键
利用数据库主键唯一的特性,解决在执行insert语句时的幂等性问题。(在分库分表情况下无效)
去重表
适用于有唯一标识的插入场景,新建一张去重表,添加唯一索引,当执行插入操作时,将唯一标识保存到去重表唯一索引字段,当重复请求时,因为有唯一约束,导致数据库抛异常回滚。
乐观锁机制
适用于更新场景,update t_goods set count = count -1 , version = version + 1 where good_id=2 and version = 1
乐观锁只是在更新数据那一刻锁表,其他时间不锁表
状态机控制
这种方法适合在有状态机流转的情况下,比如就会订单的创建和付款,订单的付款肯定是在之前,这时我们可以通过在设计状态字段时,使用int类型,并且通过值类型的大小来做幂等,比如订单的创建为0,付款成功为100。付款失败为99
对外提供接口的api如何保证幂等
对外提供接口为了支持幂等调用,接口有两个字段必须传,一个是来源source,一个是来源方序列号seq,这个两个字段在提供方系统里面做联合唯一索引,这样当第三方调用时,先在本方系统里面查询一下,是否已经处理过,返回相应处理结果;没有处理过,进行相应处理,返回结果。