我们实际系统中有很多操作,是不管做多少次,都应该产生一样的效果或返回一样的结果。 例如

  1. 前端重复提交选中的数据,应该后台只产生对应这个数据的一个反应结果;
  2. 我们发起一笔付款请求,应该只扣用户账户一次钱,当遇到网络重发或系统bug重发,也应该只扣一次钱;
  3. 发送消息,也应该只发一次
  4. 创建业务订单,一次业务请求只能创建一个,创建多个就会出大问题等等很多重要的情况都需要幂等的特性来支持。

幂等性概念

幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。 在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。例如,“getUsername()和setTrue()”函数就是一个幂等函数. 更复杂的操作幂等保证是利用唯一交易号(流水号)实现。幂等就是一个操作,不论执行多少次,产生的效果和返回的结果都是一样的。

幂等方案设计

有些操作是天然幂等的,譬如查询操作、删除操作。其他一些插入和更新操作有时候需要引入其他的机制来保证幂等,比如乐观锁、悲观锁等。这里介绍两种常用的来保证幂等的方案:利用数据库唯一索引和通过token机制来实现幂等。

利用数据库来实现幂等,

利用数据库的一些特性来实现幂等设计,可以将一些复杂的加锁解锁操作转移到数据库来处理。这样可以大大减少编码的成本。
这里用来创建唯一索引的数据必须保证是唯一的,不可出现业务上允许的重复。

token机制方式重复提交

token机制防止页面重复提交。由于网络或者重复点击的问题,可能会有重复的请求发送到服务器。利用token方式可以防止重复提交。

  1. 数据提交之前要想服务器申请token, token放到redis或者tair
  2. 提交后后台检验token,同时更新token状态
  3. 进行逻辑处理

这种方式适合web平台的管理页面,在进入页面后便拿到token,点击提交之后携带改token来请求逻辑处理,如果该token不存在,拒绝处理,如果已经处理完毕,返回处理结果。

参考资料

  1. 高并发下接口幂等性解决方案
  2. 再谈幂等机制-java杂记-51CTO博客