主题: 支付类幂等性测试分享
HI all:
最近在测试扫码支付的时候,尝试测试了支付接口的幂等性,结合实例和网上资料一并分享给大家。
-
幂等性概念
-
数学中的定义:其任意多次执行所产生的影响均与一次执行的影响相同。比如f(f(x)) = f(x).
-
HTTP协议中的定义:在HTTP/1.1规范中幂等性的定义是:HTTP方法的幂等性是指一次和多次请求某一个资源应该具有同样的副作用。其中GET,PUT, DELETE
方法是符合幂等性的,因为获取资源和删除资源无论执行多少次,产生的效果是一样的。Post方法不符合幂等性。
那么幂等性为什么在金融类的支付,扣款,提现中如此重要呢。一句话是保证资金的安全性,提现不能让用户成功提现两笔,支付也同样不能。
适用场景:
1.前端重复提交选中的数据,应该后台只产生对应这个数据的一个反应结果。
2.我们发起一笔付款请求,应该只扣用户账户一次钱,当遇到网络重发或系统bug重发,也应该只扣一次钱;
3.创建业务订单,一次业务请求只能创建一个,创建多个就会出大问题。
4.客户对一笔合同还款,一次业务请求只能成功一次,成功两次公司会穷死的(囧)
比如假设有一个从账户取钱的远程API(可以是HTTP的,也可以不是),我们暂时用类函数的方式记为:
如何服务端返回取现成功的OK请求丢失了,客户端再发一次请求,如果服务端没有做幂等性设计,那不是被取现成功两次 amount金额被减了两次。
-
如何测试幂等性
幂等性如此重要,那我们在具体的测试执行中该如何设计用例场景呢。主要有以下几种方法(有其他方法手段,欢迎补充)
-
前端重复快速点击(一般前端会做提交)
-
网络重发,比如在扫码支付时,商户在扫码时,先断网扫码一次再重连扫码
-
对同一笔订单,不同商户同时扫码
-
对同一笔业务并发请求,比如并发提现
-
Nginx重发情况(这种情况还没试过,要对nginx比较熟悉才行)
-
开发如何保证幂等性(欢迎开发大神提供更多解决方案)
-
token机制,防止页面重复提交
-
悲观锁获取数据的时候加锁获取select * from table_xxx where id='xxx' for update;注意:id字段一定是主键或者唯一索引,不然是锁表
-
乐观锁
乐观锁只是在更新数据那一刻锁表,其他时间不锁表,所以相对于悲观锁,效率更高。
-
分布式锁
-
状态机幂等
更多参考资料:
1. 高并发的核心技术-幂等的实现方案
2. RocketMQ支持事务消息机制
谢谢~~~~~
工作中测试同事分享文章