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

使用RabbitMQ实现异步支付状态通知

在支付系统中,如何确保支付状态的准确传递和处理显得尤为重要。今天,我们将以一个支付流程为例,探讨在引入RabbitMQ前后的实现和优化。

改造前

在引入RabbitMQ之前,我们通常会直接在支付方法中完成所有的操作。这包括查询支付单、判断状态、扣减余额、修改支付单状态以及通知订单服务等。以下是一个典型的实现:

@Override
@Transactional
public void tryPayOrderByBalance(PayOrderFormDTO payOrderFormDTO) {// 1.查询支付单PayOrder po = getById(payOrderFormDTO.getId());// 2.判断状态if (!PayStatus.WAIT_BUYER_PAY.equalsValue(po.getStatus())) {// 订单不是未支付,状态异常throw new BizIllegalException("交易已支付或关闭!");}// 3.尝试扣减余额userClient.deductMoney(payOrderFormDTO.getPw(), po.getAmount());// 4.修改支付单状态boolean success = markPayOrderSuccess(payOrderFormDTO.getId(), LocalDateTime.now());if (!success) {throw new BizIllegalException("交易已支付或关闭!");}// 5.修改订单状态tradeClient.markOrderPaySuccess(po.getBizOrderNo());
}
代码解读
  1. 查询支付单:通过支付单ID查询对应的支付单信息。
  2. 判断支付状态:检查支付单状态是否为“等待买家付款”,如果状态异常则抛出业务异常。
  3. 扣减用户余额:调用用户服务,尝试扣减用户余额。
  4. 修改支付单状态:如果扣减余额成功,则更新支付单状态为“支付成功”。
  5. 通知订单服务:直接调用订单服务,更新订单状态。
存在的问题
  1. 强耦合:支付服务和订单服务强耦合,修改其中一个模块可能会影响到另一个模块。
  2. 失败处理:如果在某一步骤失败,整个流程需要回滚,复杂度增加。
  3. 可扩展性差:难以扩展其他需要在支付成功后进行处理的业务逻辑。

改造后

为了提高系统的可靠性和可维护性,我们引入RabbitMQ来实现支付状态的异步通知。改造后的代码如下:

@Override
@Transactional
public void tryPayOrderByBalance(PayOrderFormDTO payOrderFormDTO) {// 1.查询支付单PayOrder po = getById(payOrderFormDTO.getId());// 2.判断状态if (!PayStatus.WAIT_BUYER_PAY.equalsValue(po.getStatus())) {// 订单不是未支付,状态异常throw new BizIllegalException("交易已支付或关闭!");}// 3.尝试扣减余额userClient.deductMoney(payOrderFormDTO.getPw(), po.getAmount());// 4.修改支付单状态boolean success = markPayOrderSuccess(payOrderFormDTO.getId(), LocalDateTime.now());if (!success) {throw new BizIllegalException("交易已支付或关闭!");}// 5.发送支付成功消息try {rabbitTemplate.convertAndSend("pay.direct", "pay.success", po.getBizOrderNo());} catch (AmqpException e) {log.error("发生支付状态通知失败,订单id:{}", po.getBizOrderNo(), e);}
}public boolean markPayOrderSuccess(Long id, LocalDateTime successTime) {return lambdaUpdate().set(PayOrder::getStatus, PayStatus.TRADE_SUCCESS.getValue()).set(PayOrder::getPaySuccessTime, successTime).eq(PayOrder::getId, id)// 支付状态的乐观锁判断.in(PayOrder::getStatus, PayStatus.NOT_COMMIT.getValue(), PayStatus.WAIT_BUYER_PAY.getValue()).update();
}
代码解读
  1. 查询支付单:通过支付单ID查询对应的支付单信息。
  2. 判断支付状态:检查支付单状态是否为“等待买家付款”,如果状态异常则抛出业务异常。
  3. 扣减用户余额:调用用户服务,尝试扣减用户余额。
  4. 修改支付单状态:如果扣减余额成功,则更新支付单状态为“支付成功”。
  5. 发送支付成功消息:通过RabbitMQ发送支付成功的消息,通知其他系统或服务支付已完成。
异步通知的实现

改造后的系统中,我们通过RabbitMQ实现了异步消息通知。以下是支付状态监听器的实现:

@Component
@RequiredArgsConstructor
public class PayStatusListener {private final IOrderService orderService;@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "trade.pay.success.queue", durable = "true"),exchange = @Exchange(name = "pay.direct"),key = "pay.success"))public void listenPaySuccess(Long orderId) {orderService.markOrderPaySuccess(orderId);}
}
监听器解读
  1. 监听队列:绑定支付成功的队列和交换机,并指定路由键。
  2. 处理消息:监听到支付成功的消息后,调用订单服务更新订单状态。

总结

通过引入RabbitMQ,我们实现了支付状态的异步通知,解决了系统强耦合、失败处理复杂、可扩展性差的问题。RabbitMQ不仅提高了系统的可靠性,还使得系统更加易于维护和扩展。

相关文章:

使用RabbitMQ实现异步支付状态通知

在支付系统中,如何确保支付状态的准确传递和处理显得尤为重要。今天,我们将以一个支付流程为例,探讨在引入RabbitMQ前后的实现和优化。 改造前 在引入RabbitMQ之前,我们通常会直接在支付方法中完成所有的操作。这包括查询支付单…...

[最短路dijkstra],启动!!!

总时间复杂度为 O ( ( n m ) log ⁡ m &#xff09; P4779 【模板】单源最短路径&#xff08;标准版&#xff09; #include<bits/stdc.h> #define ll long long #define fi first #define se second #define pb push_back #define PII pair<int,int > #define I…...

Java企业微信服务商代开发获取AccessToken示例

这里主要针对的是企业微信服务商代开发模式 文档地址 可以看到里面大致有三种token&#xff0c;一个是服务商的token&#xff0c;一个是企业授权token&#xff0c;还有一个是应用的token 这里面主要有下面几个参数 首先是服务商的 corpid 和 provider_secret &#xff0c;这个可…...

How does age change how you learn?(2)年龄如何影响学习能力?(二)

Do different people experience decline differently? 不同人经历的认知衰退会有不同吗? Do all people experience cognitive decline uniformly?Or do some people’s minds slip while others stay sharp much longer? 所有人经历的认知衰退都是一样的吗?还是有些人…...

可验证随机函数 vrf 概述

一、什么是VRF 背景: 在传统的区块链中,常用的随机算法是基于伪随机数生成器(Pseudorandom Number Generator,PRNG)的。PRNG是一种确定性算法,它根据一个初始种子生成一个看似随机的序列。在区块链中,通常使用的是伪随机数序列来选择区块的创建者、确定验证节点的轮换…...

鸿蒙双向绑定组件:TextArea、TextInput、Search、Checkbox,文本输入组件,图案解锁组件PatternLock

对象暂不支持双向绑定&#xff0c; 效果&#xff1a; 代码&#xff1a; Entry Component struct MvvmCase {StateisSelect: boolean falseStatesearchText: String ""StateinputText: string ""StateareaText: string ""build() {Grid() {G…...

JS 算法 - 计数器

theme: smartblue 题目描述 给定一个整型参数 n&#xff0c;请你编写并返回一个 counter 函数。这个 counter 函数最初返回 n&#xff0c;每次调用它时会返回前一个值加 1 的值 ( n , n 1 , n 2 &#xff0c;等等)。 示例 1&#xff1a; 输入&#xff1a; n 10 ["cal…...

JavaScript基础——JavaScript运算符

赋值运算符 算术运算符 一元运算符 三元/三目运算符 比较运算符 逻辑运算符 运算符优先级 在JavaScript中&#xff0c;常见的运算符可以包括赋值运算符、一元运算符、算术运算符&#xff08;二元运算符&#xff09;、三元/三目运算符、比较运算符、逻辑运算符等&#xff0…...

E23.【C语言】练习:不创建第三个变量实现两个整数的交换

目录 题目条件 思路1&#xff08; -&#xff09; 思路2 &#xff08;^&#xff09;(XOR) 往期推荐 1.题目条件 禁止使用以上代码 2.思路1&#xff1a; -运算 aab; ba-b; aa-b; 但这样有潜在的问题 :a&#xff0c;b存储的数字过大&#xff0c;ab可能超过范围 因此改用思路2…...

如何搭建一个web系统?

需求 搭建一个web系统。 框架 设计:墨刀 前端:Vue.js 后端:Java 算法:Python 数据库:时序数据库,介绍 部署:Jekins https://www.jenkins.io/ 文档管理:Teambition 项目管理:禅道 代码管理:Gitlab 开发流程 设计文档和原型文档&#xff0c;功能接口设计&#xff0…...

三十种未授权访问漏洞复现 合集( 二 )

未授权访问漏洞介绍 未授权访问可以理解为需要安全配置或权限认证的地址、授权页面存在缺陷&#xff0c;导致其他用户可以直接访问&#xff0c;从而引发重要权限可被操作、数据库、网站目录等敏感信息泄露。---->目录遍历 目前主要存在未授权访问漏洞的有:NFS服务&a…...

C语言学习笔记[29]:函数①

函数 在C语言中&#xff0c;函数是一段可以完成特定功能的代码&#xff0c;它们可以被重复调用。 函数的分类&#xff1a; 库函数自定义函数 库函数 在C语言中&#xff0c;库函数是由系统提供的&#xff0c;用于完成特定功能的函数&#xff0c;这些函数被集合在一起&#…...

使用Springboot + netty 打造聊天服务之Nacos集群问题记录

目录 1、前言1.1、方法一1.2、方法二 2、方案二实战2.1、在netty服务里加上ws连接、中断事件2.2、在netty服务里加上消息服务 4、总结 使用Springboot netty 打造聊天服务系列文章 第一章 初始搭建工程 第二章 Nacos集群问题记录 1、前言 在使用Springboot Nacos Netty(Web…...

全网唯一!R语言顶刊配色包TheBestColors

与Matlab相比&#xff0c;R语言在绘图方面有着天然的优势。 比如在配色方面&#xff0c;R语言有各式各样现成的包&#xff0c;按理说配色这种事应该很方便才对。 但实际体验下来&#xff0c;发现似乎不是那么回事。 首先&#xff0c;你很难记住每个包的调用方法以及每种配色…...

链表题型思路错误总结

常见题目 206. 反转链表 关键点&#xff1a;定义前置指针。 在给cur.next复制前&#xff0c;需要定义好next节点防止断链。 public ListNode reverseList(ListNode head) {if (head null || head.next null) {return head;}ListNode pre null;ListNode cur head;while(cur…...

算法学习day28

一、寻找右区间(二分法) 题意&#xff1a;题目很容易理解 但是转换为二分法有点晦涩 给你一个区间数组 intervals &#xff0c;其中 intervals[i] [starti, endi] &#xff0c;且每个 starti 都 不同 。区间 i 的 右侧区间 可以记作区间 j &#xff0c;并满足 startj > e…...

C语言基础题:迷宫寻路(C语言版)

1.题目描述 机器猫被困在一个矩形迷宫里。 迷宫可以视为一个n x m 矩阵&#xff0c;每个位置要么是空地&#xff0c;要么是墙。机器猫只能从一个空地走到其上、下、左、右的空地。 机器猫初始时位于(1,1)的位置&#xff0c;问能否走到(n,m)位置。 2.输入格式 第一行&#xff0…...

力扣-1两数之和2两数相加-2024/8/3

1、两数之和 解法一 暴力法&#xff08;2个for循环&#xff09; class Solution:def twoSum(self, nums: List[int], target: int) -> List[int]:for ii in range(len(nums)):for jj in range(ii1, len(nums)):if nums[ii]nums[jj] target:return [ii,jj]解法二 哈希表法…...

简站WordPress主题 专业的WordPress建站服务商

简站WordPress主题是一款备受推崇的WordPress主题&#xff0c;以其简洁、实用、无插件和更安全的特性脱颖而出。以下是关于简站WordPress主题的一些详细分析&#xff1a; 简站WordPress主题采用了扁平化设计风格&#xff0c;界面简洁明了&#xff0c;这使得网站看起来更加专业…...

Final Shell for Mac 虚拟机连接工具【简单易操作,轻松上手】【开发所需连接工具】

Mac分享吧 文章目录 效果一、下载软件二、安装软件三、运行测试安装完成&#xff01;&#xff01;&#xff01; 效果 一、下载软件 下载软件 链接&#xff1a;http://www.macfxb.cn 二、安装软件 三、运行测试 安装完成&#xff01;&#xff01;&#xff01;...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...