接口的幂等性如何设计
接口的幂等性指用户对于同一个接口使用相同的参数一次请求或者多次请求的接口应该是一致的,不会因为多次请求而产生副作用。
比如用户支付扣款接口,一次调用支付和多次调用都应该是成功,而不会多次扣费。
增删改查中,主要是增和改需要注意幂等性。
-
查询天然是幂等的。
-
删除一条数据一次多次和多次应该都是将该条数据删除。
-
更新操作。更新操作大多数都是幂等的,但是如果更新操作是对字段的值进行增减就不是幂等的。比如用户消费后,需要减少用户的余额,调用一次和调用多次,可能造成用户的余额被多次减少。
-
新增。比如调用新增客户的接口,新增同一个客户,调用一次或者调用多次,都应该只在系统插入一条用户记录。
解决方法
-
使用uuid。发送请求之前,先调用接口获取一个uuid,请求带上这个uuid,如果请求完成这个uuid会持久化到数据库,请求过来的时候先检查uuid是否已经存在,如果已经存在就不继续处理请求。
这个uuid是订单id,客户id等,也可以是一个无业务意义的字段。 -
使用数据库的唯一索引。不允许重复的值,可以建一个唯一索引,如果更新了重复的数据,数据库就会报错,事务就会回滚。
-
使用版本控制,给数据加一个版本字段。
这个也就是一种乐观锁的实现,请求之前调用接口获取当前数据的版本号,处理请求的时候,如果请求带来的版本号不等于数据当前版本号,将更新失败并回滚事务,只有版本匹配的可以更新。如果更新成功后数据版本号增加。
这样也能实现相同接口调用的多次请求,只会修改一次数据。 -
使用业务字段值控制 更新语句的where条件的加上更新字段的前提条件。
比如修改商品数量,客户将商品当前数量也作为请求参数加入更新的where条件:update goods set num=num-1 where num=3;
那么多次请求只要有一次修改成果,其它的请求将不会修改数据。