幂等问题的处理方案

507 阅读3分钟

什么是幂等性

  幂等性,一般分布环境下会遇到的常见问题,指多次操作所得到结果一样。

  一般接口调用需要处理幂等性问题,有时候是需要防止幂等操作导致出现数据重复等问题,有时候需要保证幂等发生。

 像我们的sql操作中:

  insert : insert每次都会新增一条数据,是非幂等操作。

  update : update 更新同一个值时,结果都一样,是幂等操作。

  delete : 删除同一条数据结果都一样,是幂等操作。

   select : 查询同一条数据结果都一样,是幂等操作。

  这些sql操作关联到相应接口中,就会出现各种幂等问题。

   比如我们知道,浏览器与后端服务是通过http(https)请求进行交互,而http请求的底层是通过tcp封装的,tcp有超时重试机制,在http协议封装时,对于因为网络抖动或者其他问题导致的超时确认数据或者丢失数据,会进行重发,这时候就产生了幂等操作。如果我们没有做一些幂等处理,就很容易产生重复数据或者相同调用结果,针对这种情况,我们需要保证结果幂等,所以就不能因为网络抖动重复请求而产生两条数据。

  还有一种情况针对于我们接口管理平台所引发的接口重复消费,或者mq消息队列的消息重复消费,都会产生幂等问题。

……

保证幂等性与防止幂等性

  对于类似因为网络抖动或者其他原因而产生的重复请求,我们应该保证其结果幂等,也就是说不能同一条数据产生多种结果。

  对于这种问题的处理,常见的方案有:

乐观锁方案

  比如update类型的接口操作,那我们在设计数据库表的时候就可以设计一个version字段,作为乐观锁,每次进行update时比对其版本,如果版本不一致,说明该请求已过期,不让其成功。

  还可以通过时间戳实现乐观锁,进行幂等校验。

统一id方案(redis)

还有在分布式环境下我们可以获取统一的id(通过redis来实现),在消费完成后,该id移除,来保证其幂等性,也就是保证消息或者接口不重复消费。

使用唯一id来保证幂等(下游传递或者数据库表主键)

 区分redis实现的统一id,这个id类似表主键id,通过其来保证结果幂等性,也就是不会产生重复数据。

使用token来保证幂等

 可以防止前端页面重复提交等问题,参考如下示意图: test13 (1).png