什么是幂等性
幂等性:就是用户对于同一操作发起的一次请求,或者多次请求的结果是一致的,多次请求不会影响系统状态。
没有幂等性的情况
最常见的例子就是支付,比如用户购买商品后进行支付,支付扣款成功,但是返回结果的时候网络异常,用户再次点击按钮,那么此时会进行第二次扣款,返回结果成功,用户查询余额发现扣了两次钱,流水记录也变成了两条。这不是坑爹嘛。
又可能用户不知道怎么得对一个订单发起了两次支付请求,但是这两个请求被负载均衡落在不同的机器上,如果没有做分布式幂等性,那么也会扣款两次。
如何实现幂等性
实现幂等性,就是对一个接口实现,多次发起同一个请求,这个接口得保证结果是准确的,针对这个案例来说就是不能多扣款、不能多插入一条数据。
业务层面上保证幂等性:
- 每个请求必须有一个唯一的标识,比如每个订单支付请求都包含订单 id,订单id是唯一的,且每个订单只能支付一次。
- 每次处理完请求之后,必须有一个记录标识这个请求处理过了。常见的方案是在 mysql 中记录这个订单的支付流水。
- 每次接收请求需要进行判断,判断之前是否处理过。如果有一个订单已经支付了,就已经有了一条支付流水,那么如果重复发送这个请求,则此时先插入支付流水,如果 orderId 已经存在,唯一键约束生效,报错,插入失败,那么就不用再扣款了。
实际运作过程中,还是要结合自己的业务来,比如还可以利用 redis 做幂等性,支付请求处理后可以写一个标识到 redis 里面去,比如 set order_id payed,下一次重复请求过来了,先查 redis 的 order_id 对应的 value,如果是 payed 就说明已经支付过了,那么就不要重复支付了。