首页 > 其他分享 >通过模拟发送mq消息来测试实现-依据支付凭证不能重复入账

通过模拟发送mq消息来测试实现-依据支付凭证不能重复入账

时间:2024-12-12 19:31:57浏览次数:3  
标签:凭证 记录 入账 redisKey 查询 mq 支付 MQ 收银台

通过模拟发送mq消息来测试实现-依据支付凭证不能重复入账

1.依据MQ消息的json串转换为md5记录,作为收银台表的唯一约束。如果支付状态发生变化,则payMd5会跟随着变化。

2.消息流程
客户支付成功 > 微信支付微服务接收到微信支付的异步通知回调通知 > 发送给支付网关微服务(发送mq消息在本地数据库落库记录) >
发送支付成功的MQ消息,rabbitmq topic方式 (防止MQ消息在服务重启等丢失,加固方案:同时加上接口推送双重保险)

业务微服务接收到支付成功的通知
1.首先检查该条记录的唯一约束字段payMd5,select查询数据库收银台表是否存在且状态是否成功。
2.存在且成功,则不做处理。 >> 幂等处理,防止Mq和接口的双重通知,接口推送延迟1秒处理,防止造成数据的重复。
3.不存在,则更新添加收银台表记录,更新费用总表记录,更新费用明细进出流水记录。

问题点:
支付网关发送MQ时间,收银台表创建时间,业务系统的接收MQ时间都是同一时间,到秒。
且支付网关发送了2条记录。导致业务系统费用总表记账金额*2倍,费用明细进出流水记录2条。收银台表因为加了payMd5数据库唯一约束,只有一条记录。

排查推测点:
问题可能出在:mysql并发查询,select查询数据库收银台表是否存在且状态是否成功。 并发查询的时候,没有查询出来结果,可能上一个事务没有提交等原因。
导致记录重复了。
--如果MySQL并发查询导致没有查询结果,可能是因为查询时刻数据被其他事务修改或删除。--
--MySQL在执行高并发查询时,可能会出现数据重复,这通常是因为事务没有正确管理,导致查询期间可以看到其他事务尚未提交的数据。--

解决方法:
在mysql select查询的验证的提前,加上一层redis锁来防止重复,锁定时间:60秒

String redisKey = "redisKey" + payMd5;
                //走redis查询 第一层逻辑
                redisKey = redisKey+notifyDataVo.getPayMd5();
                if(stringRedisTemplate.hasKey(redisKey)){
                    //已被锁定,直接返回,幂等结果返回true,提前返回结束,不在继续后续的业务逻辑的执行。
                    return true;
                }
                //锁定60秒
                if(StringUtils.isNotBlank(redisKey)){
                    stringRedisTemplate.opsForValue().set(redisKey,"1",60, TimeUnit.SECONDS);
                }
                
                //走数据库查询 第二层逻辑
                boolean flag = cashierService.checkCashierPayMd5(notifyDataVo);
                if(flag) {  //成功
                    return flag;
                }
            }
        }

测试方法:
MQ消息通过rabbitmq客户端重复多次发送,查看拦截日志。

link:支付回调MQ消息的幂等处理及MD5字符串es中的使用及支付宝预授权完成
https://www.cnblogs.com/oktokeep/p/17263287.html

标签:凭证,记录,入账,redisKey,查询,mq,支付,MQ,收银台
From: https://www.cnblogs.com/oktokeep/p/18603234

相关文章

  • 四大主流消息队列 场景化选型指导:kafka、rocketmq、rabbitmq、pulsar
    探讨消息队列在软件开发中的应用与选择在日常的软件开发过程中,我们常常会遇到系统间的异步通信、流量削峰填谷、日志收集等需求。这时,消息队列就成为了解决这类问题的有效工具之一。比如,在电商平台中,当用户下单时,订单信息不仅需要立即保存到数据库中,还需要同步更新库存、生成物流......
  • 1、消息队列框架:RabbitMQ - 开源项目研究文章
    RabbitMQ是一个开源的消息代理和队列服务器,它使用AMQP(高级消息队列协议)来实现跨语言和跨平台的消息传递。它由Erlang语言编写,支持多种消息队列协议,如STOMP和MQTT,并且提供了多种语言的客户端支持。RabbitMQ的核心组件包括Broker、VirtualHost、Connection、Chan......
  • 记一次与Rocketmq的进程异常行为修复过程
    rocketmq部署在docker中。前段时间,阿里云服务器发出安全告警看到curl和startfsrv.sh,下意识地认为这是下载了一个恶意脚本,接下来把恶意脚本找到,分析内容,修复的思路就有了。但是找到脚本之后,创建时间是2019年,同时也只是rocketmq一个正常的启动脚本。这样思路就断了。接下来只能......
  • MQTT协议史上最全解析(纯干货分享)
    目录MQTT是什么?一些术语解释MQTT特点MQTT控制报文格式十四种控制报文1号控制报文:CONNECT–连接到服务端2号控制报文:CONNACK–确认连接请求3号控制报文:PUBLISH–发布消息4号控制报文:PUBACK–发布确认5号控制报文:PUBREC–发布收到(QoS2,第一步)6号控制报文:PU......
  • RabbitMQ——CLI 管理工具 rabbitmqadmin
    前言一般情况下,我们会使用rabbitmq_management插件,通过WebUI的方式来监控和操作RabbitMQ(端口15672),但有时候命令的方式会更加方便一些,RabbitMQ提供了CLI管理工具rabbitmqadmin,其实就是基于RabbitMQ的HTTPAPI,用Python写的一个脚本。rabbitmqadmin提供了下面功......
  • 使用ESP32做一个MQTT协议的公网对讲机
    此篇文章在2022年8月14日被记录使用MQTT做一个公网对讲机上一篇博客中,使用ESP32与ESP-NOW协议做了一个短距离对讲机(链接),发布了一个视频在B站评论区中,很多B友希望可以实现无限距离对讲,这样的话需要服务器转发,刚开始我想使用python写一个TCP或者UDP的转发功能,但是考虑到很多小......
  • Linux下Mosquitto MQTT代理的安装与配置指南
    1.引言MQTT(MessageQueuingTelemetryTransport)是一种轻量级的、基于发布/订阅模式的消息传输协议,广泛应用于物联网(IoT)领域。Mosquitto是一个开源的MQTT代理,它支持MQTT协议3.1和3.1.1,适用于各种设备和平台。本文将详细介绍如何在Linux系统下安装和配置MosquittoMQTT代理。......
  • 话说MQTTX工具
    MQTTX是一个强大的跨平台MQTT客户端工具。开发公司EMQ也是非常具有实力的研发公司。以前有关mqtt调试工具都是自己写的程序,近日也试用了一下行业明灯MQTTX,使用时有些问题1、既然支持多标签页的主题订阅和发送,为社么不把每个主题的发送数和接收数显示出来,而是只写这个连接的......
  • 排查MQ消息发送和接收
    排查MQ消息发送和接收TemplateCodeSmsMqmq=newTemplateCodeSmsMq();mq.setMobile(record.getMobile());mq.setTemplateCode("mySmsCode1");Map<String,Object>map=newHashMap<>();map.put("plateNum",......
  • solon 集成 rocketmq5 sdk
    使用rocketmq5是比较简单的事情。也有些同学对sdk原始接口会陌生,会希望有个集成的示例。<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-client-java</artifactId><version>${rocketmq5.version}</version></depen......