接口幂等性这么重要,它是什么?怎么实现?
发布日期:2021-10-20 03:26:41 浏览次数:2 分类:技术文章

本文共 1655 字,大约阅读时间需要 5 分钟。

什么是幂等性?

对于同一笔业务操作,不管调用多少次,得到的结果都是一样的。

幂等性设计

我们以对接支付宝充值为例,来分析支付回调接口如何设计?

如果我们系统中对接过支付宝充值功能的,我们需要给支付宝提供一个回调接口,支付宝回调信息中会携带(out_trade_no【商户订单号】,trade_no【支付宝交易号】),trade_no在支付宝中是唯一的,out_trade_no在商户系统中是唯一的。

回调接口实现有以下实现方式。

方式1(普通方式)

过程如下:

1.接收到支付宝支付成功请求

上面的过程,对于同一笔订单,如果支付宝同时通知多次,会出现什么问题?当多次通知同时到达第2步时候,查询订单都是未处理的,会继续向下执行,最终本地会给用户加两次钱。

此方式适用于单机其,通知按顺序执行的情况,只能用于自己写着玩玩。

方式2(jvm加锁方式)

方式1中由于并发出现了问题,此时我们使用java中的Lock加锁,来防止并发操作,过程如下:

1.接收到支付宝支付成功请求

分析问题:

方式3(悲观锁方式)

使用数据库中悲观锁实现。悲观锁类似于方式二中的Lock,只不过是依靠数据库来实现的。数据中悲观锁使用for update来实现,过程如下:

1.接收到支付宝支付成功请求

select * from t_order where order_id = trade_no for update;

4.判断订单是已处理

重点在于for update,对for update,做一下说明:

方式3可以正常实现我们需要的效果,能保证接口的幂等性,不过存在一些缺点:

方式4(乐观锁方式)

依靠数据库中的乐观锁来实现。

1.接收到支付宝支付成功请求

select * from t_order where order_id = trade_no;

3.判断订单是已处理

update t_order set status = 1 where order_id = trade_no where status = 0;//上面的update操作会返回影响的行数numif(num==1){ //表示更新成功 提交事务;}else{ //表示更新失败 回滚事务;}

注意:

方式5(唯一约束方式)

依赖数据库中唯一约束来实现。

我们可以创建一个表:

CREATE TABLE `t_uq_dipose` (  `id` bigint(20) NOT NULL AUTO_INCREMENT,  `ref_type` varchar(32) NOT NULL DEFAULT '' COMMENT '关联对象类型',  `ref_id` varchar(64) NOT NULL DEFAULT '' COMMENT '关联对象id',  PRIMARY KEY (`id`),  UNIQUE KEY `uq_1` (`ref_type`,`ref_id`) COMMENT '保证业务唯一性');

对于任何一个业务,有一个业务类型(ref_type),业务有一个全局唯一的订单号,业务来的时候,先查询t_uq_dipose表中是否存在相关记录,若不存在,继续放行。

过程如下:

1.接收到支付宝支付成功请求

select * from t_uq_dipose where ref_type = '充值订单' and ref_id = trade_no;

3.判断订单是已处理

try{    insert into t_uq_dipose (ref_type,ref_id) values ('充值订单',trade_no);    //提交本地事务:}catch(Exception e){    //回滚本地事务;}

说明:

关于消息服务中,消费者如何保证消息处理的幂等性?

总结

  1. 实现幂等性常见的方式有:悲观锁(for update)、乐观锁、唯一约束

本文转载自:路人甲Java

往期推荐








640?wx_fmt=jpeg

640?

点个在看,证明你还爱我

转载地址:https://blog.csdn.net/u014400934/article/details/101731174 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:消灭 Java 代码的“坏味道”
下一篇:程序员相亲图鉴

发表评论

最新留言

表示我来过!
[***.191.171.23]2022年06月01日 04时42分08秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

最新文章

OC动画组 2019-12-13 02:35:52
关键帧动画 2019-12-13 02:35:52
ORALCE用户管理 2019-12-13 02:35:50
三范式讲解 2019-12-13 02:35:50
django csrf解决办法 2019-12-13 02:35:50
c++模板学习一 2019-12-13 02:35:50
因为热爱,所以选择! 2019-12-13 02:35:50
JSON介绍 2019-12-13 02:35:51
数据缓存 2019-12-13 02:35:51
Foundation构架秘籍 2019-12-13 02:35:51
在使用poi的时候找不到方法的解决办法 2019-12-13 02:35:49
vue 开发命名规范 2019-12-13 02:35:49
vue全局组件自动注册,无需再单独引用 2019-12-13 02:35:49
关于james邮箱服务器配置、维护以及常见问题定位 2019-12-13 02:35:49
ORA-01843的错误.这个错误代表无效的月份一般在日期转化的时候会提示 2019-12-13 02:35:49
透视图切换 2019-12-13 02:35:47
jQuery获取iframe内的DOM对象 2019-12-13 02:35:47
你会做Web上的用户登录功能吗? 2019-12-13 02:35:47
隐藏文件的好方法 2019-12-13 02:35:48
ie和火狐都兼容的背景图片设置方式 2019-12-13 02:35:48