当前位置: 首页 > news >正文

微服务项目:尚融宝(52)(核心业务流程:充值服务(3))

一、接口幂等性原则

1、什么是接口幂等性

接口幂等性就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次调用而产生了副作用。

举个最简单的例子,那就是支付,用户购买商品后支付,支付扣款成功,但是返回结果的时候网络异常,此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额返发现多扣钱了,流水记录也变成了两条...这就没有保证接口的幂等性

2、回调重试

汇付宝向尚融宝发起回调,如果没有收到正确的响应 "success",则尚融宝会发起重试

汇付宝中的相关代码如下:

@Slf4j
public class NotifyThread implements Runnable {

    private int count = 1;
    private String notifyUrl;
    private Map<String, Object> paramMap;

    public NotifyThread(){}

    public NotifyThread(String notifyUrl, Map<String, Object> paramMap) {
        this.notifyUrl = notifyUrl;
        this.paramMap = paramMap;
    }

    @Override
    public void run() {
        task();
    }

    private void task() {
        String result = SignUtil.sendRequest(paramMap,notifyUrl);
        log.info(notifyUrl + ":" + result + " count:" + count);
        if(!"success".equals(result)) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //ScheduledTask.queue.offer(new NotifyVo(notifyUrl, paramMap));
            count++;
            if(count <= 5) {
                task();
                log.info("失败重试:" + JSON.toJSONString(this));
            }
        }
    }
}

3、存在的问题

当回调重试时,金额和流水会重复增加

 

二、解决方案

1、设置唯一索引

设置了唯一索引后,即使回调重复执行,遇到唯一索引,就会抛出异常,从而使事务回滚。

 

2、判断流水是否存在

判断流水如果存在,则从业务方法中直接退出

接口:TransFlowService

boolean isSaveTransFlow(String agentBillNo);

实现:TransFlowServiceImpl 

@Override
public boolean isSaveTransFlow(String agentBillNo) {
    QueryWrapper<TransFlow> queryWrapper = new QueryWrapper();
    queryWrapper.eq("trans_no", agentBillNo);
    int count = baseMapper.selectCount(queryWrapper);
    if(count > 0) {
        return true;
    }
    return false;
}

调用 :UserAccountServiceImpl 

@Transactional(rollbackFor = Exception.class)
@Override
public void notify(Map<String, Object> paramMap) {

    log.info("充值成功:" + JSONObject.toJSONString(paramMap));

    //判断交易流水是否存在
    String agentBillNo = (String)paramMap.get("agentBillNo"); //商户充值订单号
    boolean isSave = transFlowService.isSaveTransFlow(agentBillNo);
    if(isSave){
        log.warn("幂等性返回");
        return;
    }

   ......
       
    //增加交易流水
    //agentBillNo = (String)paramMap.get("agentBillNo"); //商户充值订单号

}

今日分享 

 1. 硬件的目的:为了运行软件给它的一些指令。我们可以优先从硬件中提取出这三个主要的东西,分别是: CPU,内存,硬盘

       2. 在现实生活中,人脑是用来计算的,在计算机中,用来计算的是什么呢?当然是CPU了。多数CPU都有两种模式,即内核态与用户态。这里的即内核态与用户态将会在下面的内容中讲到。

       3.如果我们把计算机理解为人的大脑,我们可以总结为几句话:

               CPU是人的大脑,负责运算

        内存是人的记忆,负责临时存储

        硬盘是人的笔记本,负责永久存储

        输入设备是人的耳朵或眼睛,负责接受外部的信息传给CPU

        以上所有的设备都通过总线连接,总线相当于人的神经

相关文章:

  • python的小作业
  • 2022届计算机毕业论文(设计)学生选题参考合集推荐收藏
  • AI艺术的背后:详解文本生成图像模型【基于GAN】
  • NR 物理层编码 - slide4 循环码Cyclic Code
  • 内网渗透-内网信息收集
  • 新学期、新目标、迎接新的自己
  • 2022年重庆自考如何报名,有哪些条件和要求?
  • 70 QDateTime时间戳转换有误
  • 中科大给师生们发了一封钓鱼邮件 结果3000多人上当了
  • ROS之rviz文件的加载和保存
  • ESP8266-Arduino编程实例-VCNL4040趋近传感器
  • 机器学习模型1——线性回归和逻辑回归
  • 基于WEB在线音乐工厂的设计与实现
  • 基于 CoreDNS 和 K8s 构建云原生场景下的企业级 DNS
  • 快速学习MyBatis|实战项目详解
  • 【Linux系统编程】快速查找errno错误码信息
  • Fundebug计费标准解释:事件数是如何定义的?
  • IP路由与转发
  • Java程序员幽默爆笑锦集
  • Js基础——数据类型之Null和Undefined
  • Linux链接文件
  • Lucene解析 - 基本概念
  • React as a UI Runtime(五、列表)
  • ReactNative开发常用的三方模块
  • Travix是如何部署应用程序到Kubernetes上的
  • 给新手的新浪微博 SDK 集成教程【一】
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 前端学习笔记之原型——一张图说明`prototype`和`__proto__`的区别
  • 详解NodeJs流之一
  • 小程序button引导用户授权
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • 栈实现走出迷宫(C++)
  • 最近的计划
  • ​​​​​​​Installing ROS on the Raspberry Pi
  • ​卜东波研究员:高观点下的少儿计算思维
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (done) 两个矩阵 “相似” 是什么意思?
  • (Pytorch框架)神经网络输出维度调试,做出我们自己的网络来!!(详细教程~)
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (转载)从 Java 代码到 Java 堆
  • .NET BackgroundWorker
  • .net core webapi Startup 注入ConfigurePrimaryHttpMessageHandler
  • .net core 控制台应用程序读取配置文件app.config
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划
  • .Net8 Blazor 尝鲜
  • .net利用SQLBulkCopy进行数据库之间的大批量数据传递
  • .NET连接MongoDB数据库实例教程
  • .NET应用架构设计:原则、模式与实践 目录预览
  • /dev/sda2 is mounted; will not make a filesystem here!
  • @RequestParam详解
  • [AIGC] Nacos:一个简单 yet powerful 的配置中心和服务注册中心
  • [Android 13]Input系列--获取触摸窗口