接口幂等性解决方案

接口幂等性解决方案

后端幂等性实现:

  • 唯一索引(简单粗暴的办法)
    例如,如果我的id是自增主键,一定会有幂等性问题,因为会产生多条数据相同,但主键不同的数据。那如果是业务逐渐呢?我们把多个字段简历唯一索引,比如name,age,type三个字段建立唯一索引。这样就ok了!即使我的id相同,数据库也不会报错。
    此方案可以限制重复插入数据,当插入数据重复时数据库就会抛异常,保证不会出现脏数据。比如我们在用户注册场景,存贮用户场景等,要求一些唯一记录的场景下可以使用。

  • token验证。比如客户端进入一个支付页面后,后端生成一个token返回给前端,当每次点击支付的时候都带上这个token,请求后端支付接口时进行验证。提交后后台校验token,执行提交逻辑,提交成功同时删除token,生成新的token更新redis ,这样当第一次提交后token更新了,页面再次提交携带的token是已删除的token后台验证会失败不让提交如果不是同一个token就不予处理。

  • 乐观锁(既保证效率又保证幂等)

#每次更新version版本号+1,如果版本号不一致更新不成功!
<update id="update" parameterType="Order">
 update t_order set status=#{status},version = version+1 where orderId=#{orderId} and version = #{version}
</update>
public boolean pay(String orderId,UserAccount userAccount){
	//查询订单
	Order order = orderMapper.selectById(orderId);
	if(order.getStatus == 0){//是未支付状态
		order.setStatus(1);//设置支付成功状态
		int row = orderMapper.update(order);//更新order
		if(row > 0){//更新成功,执行支付!
			userAccountMapper.pay(order.getId,userAccount.getUserId);
			return true;
		}else{
			return false;//支付失败
		}	
		return true;
	}else{
		return true;//已经支付
	}
}
  • 增加防重表(这种方式和乐观锁原理差不多)
    比如我们可以将唯一主键(orderId)作为防重表的唯一索引,如果请求支付时就向防重表里查一条记录,插入成功才能去支付,插入失败就不让执行支付操作。

  • 分布式锁
    在进入方法时,先去获取锁,假如获取到锁,就继续后面的流程。假如没有获取到锁,就等待锁的释放直到获取到锁,当执行完方法时,释放锁,当然,锁要设个超时时间,防止意外没有释放到锁,它可以用来解决分布式系统的幂等性;
    常用的分布式锁实现方案是redis和zookeeper等工具。
    使用分布式锁类似于防重表,将防重并发放到了缓存中,较为高效。思路相同,同一时间只能完成一次支付请求。

  • 缓冲队列
    将请求都快速接收下来,放入缓冲队列,后续使用异步任务处理队列中的请求,过滤掉重复的请求。

前端可执行的一些方案:

  • 按钮加loading,一段时间内只让点击一次。
  • 点击完就跳转页面,不让多停留。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值