定位线上同步锁仍然重复扣费的Bug定位及Redis分布式锁解决方案

在实际生产环境中,处理订单的并发请求时,我们经常会遇到重复扣费的问题。本文将通过一个具体的代码示例,分析在使用同步锁时仍然导致重复扣费的原因,并提供一个基于Redis分布式锁的解决方案。

背景:这个案例出现在商家在小程序端接单重复扣费,PC端也能接单,并且PC端和小程序端不是一套代码,但是接单的代码几乎一致

一、问题描述

在以下代码中,OrderServiceImpl 类使用了 Java 的同步锁来保证对订单状态变更的操作是线程安全的:

public class OrderServiceImpl {public Operating orderStateChange(OrderStateReq orderStateReq) {synchronized (OrderServiceImpl.class) {//订单idInteger orderId = orderStateReq.getOrderId();//根据订单id查看订单是否满足扣费  不满足则抛异常  满足则扣费}}  
}

二、问题分析

尽管我们在 orderStateChange 方法中使用了同步锁,但仍然可能导致重复扣费的问题,原因有以下几点:

锁粒度过大:synchronized (OrderServiceImpl.class) 锁定的是整个类,这样虽然可以避免多个线程同时进入临界区,但在分布式环境下,这种锁机制无法跨JVM工作。

锁的范围有限:Java 的 synchronized 锁仅在单个 JVM 中有效,如果你的应用程序部署在多台服务器上,每个服务器上的 JVM 都会有自己的锁,这就无法避免分布式环境下的并发问题。

业务逻辑不完善:即使在单机环境中,锁住整个类也会导致性能瓶颈,因为所有订单处理请求都必须排队进入同步块,无法充分利用多线程的优势。

三、解决方案

为了解决上述问题,我们可以使用 Redis 分布式锁。Redis 分布式锁的特点是可以跨多个 JVM 保证唯一性,从而避免分布式环境下的并发问题。

1. 引入 Redis 依赖
首先,在你的项目中引入 Redis 相关依赖(以 Spring Boot 为例):

<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.16.2</version></dependency>

2. 实现 Redis 分布式锁
然后,我们实现一个简单的 Redis 分布式锁机制。可以使用 Redisson 库,这个库封装了 Redis 锁的实现,使用起来非常方便。

import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import java.util.concurrent.TimeUnit;public class RedisLockUtil {private static RedissonClient redissonClient;// 有指定库和密码也需要赋值static {Config config = new Config();config.useSingleServer().setAddress("redis://localhost:6379");config.useSingleServer().setPassword("redisPassword");config.useSingleServer().setDatabase("database");redissonClient = Redisson.create(config);}public static RLock getLock(String lockKey) {return redissonClient.getLock(lockKey);}
}

3. 使用 Redis 分布式锁
在 OrderServiceImpl 中使用 Redis 分布式锁来实现订单状态变更操作:

import org.redisson.api.RLock;public class OrderServiceImpl {public Operating orderStateChange(OrderStateReq orderStateReq) {String lockKey = "orderLock:" + orderStateReq.getOrderId();RLock lock = RedisLockUtil.getLock(lockKey);try {// 尝试加锁,等待时间为10秒,锁超时时间为30秒if (lock.tryLock(10, 30, TimeUnit.SECONDS)) {try {//订单idInteger orderId = orderStateReq.getOrderId();//根据订单id查看订单是否满足扣费  不满足则抛异常  满足则扣费} finally {lock.unlock();}} else {// 获取锁失败,处理逻辑throw new RuntimeException("获取锁失败,请稍后再试");}} catch (InterruptedException e) {Thread.currentThread().interrupt();throw new RuntimeException("线程中断", e);}}
}

在使用了分布式锁后上线一周内让DB再查看已经没有了重复扣费现象

四、总结

通过以上步骤,我们可以解决同步锁在分布式环境下无法避免重复扣费的问题。使用 Redis 分布式锁,不仅能在多台服务器上保证锁的唯一性,还能提高系统的并发处理能力,避免性能瓶颈。

希望本文对你在解决分布式系统中的并发问题有所帮助,如果有任何问题或建议,欢迎交流讨论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/40035.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024年洗地机哪个牌子好?内行人最建议这4个:清洁力口碑公认都不错

在当代生活中&#xff0c;洗地机可以称得上是一款必备“神器”&#xff0c;劳累的清洁、繁忙的时间、漫天纷飞的宠物毛发&#xff0c;都是家庭清洁面前的一座座大山。而洗地机的出现&#xff0c;完美解决了这些问题&#xff0c;既节约出了很多时间&#xff0c;又达到了很好的清…

Pspice添加新的元器件

1.下载好的Pspice的模型文件。 2.将模型文件的&#xff0c;识别类型修改为 lib 选择Pspice的模型路径 会立马跳出&#xff0c;下面的这个窗口。 核实元器件图形&#xff0c;没问题。 添加Pspic仿真模型文件 验证&#xff0c;是否添加模型文件成功 使用模型文件

linux less命令详解

less是一个在 Linux 和类 Unix 系统中常用的分页查看工具&#xff0c;它允许用户查看长文件或输出&#xff0c;同时提供了向前和向后滚动的功能&#xff0c;而不需要一次性将整个文件加载到内存中。这对于查看大文件特别有用&#xff0c;因为它比 cat 命令更加灵活和高效。 le…

完全理解C语言函数

文章目录 1.函数是什么2.C语言中的函数分类2.1 库函数2.1.1 如何使用库函数 2.2自定义函数 3.函数的参数3.1 实际参数&#xff08;实参&#xff09;3.2 形式参数&#xff08;形参&#xff09; 4.函数调用4.1传值调用4.2 传址调用4.3 练习 5.函数的嵌套调用和链式访问5.1 嵌套调…

java连接AD(Microsoft Active Directory)模拟用户登录认证

文章目录 一、背景二、页面效果三、代码LdapLoginRequest请求实体类Response返回结果MsgADTest测试类补充说明代码 四、认证结果认证成功认证失败 本人其他相关文章链接 一、背景 亲测可用,之前搜索了很多博客&#xff0c;啥样的都有&#xff0c;就是不介绍报错以及配置用处&a…

图论学习 c++Ford-Fulkerson 方法

Ford-Fulkerson算法是用于求解最大流问题的一种经典算法。其核心思想是通过不断寻找增广路径来增加流量&#xff0c;直到找不到增广路径为止。每次找到一条增广路径&#xff0c;就增加相应的流量&#xff0c;更新残余网络。简单来说就是Ford-Fulkerson算法的工作过程&#xff0…

【探索Linux】P.37(传输层 —— TCP协议通信机制 | 确认应答(ACK)机制 | 超时重传机制)

阅读导航 引言一、确认应答(ACK)机制1. 成功接收2. 过程中存在丢包3. 引入序列号&#xff08;1&#xff09;序列号的定义&#xff08;2&#xff09;序列号的作用&#xff08;3&#xff09;序列号的工作原理&#xff08;4&#xff09;序列号和确认应答号 二、超时重传机制1. 超时…

基于Java的壁纸网站设计与实现

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

ERP的模块说明

ERP的模块&#xff1a;物料管理、销售管理、生产管理)、财务管理、质量管理、人力资源管理、项目管理、仓储管理(WMS)、供应商管理(SRM)等功能模块 ERP流程通常涉及以下几个关键步骤&#xff1a; 制定生产计划&#xff1a;这是ERP流程的第一步&#xff0c;需要根据产品预测和订…

Oracle中http的post的用法和例子

在Oracle数据库中&#xff0c;直接执行HTTP POST请求并不是数据库核心功能的一部分。但是&#xff0c;你可以通过Oracle的PL/SQL程序结合一些额外的工具或库来实现这一功能。 以下是一个使用Oracle UTL_HTTP包&#xff08;Oracle提供的用于HTTP通信的PL/SQL包&#xff09;来发…

nftables(1)基本原理

简介 nftables 是 Linux 内核中用于数据包分类的现代框架&#xff0c;用来替代旧的 iptables&#xff08;包括 ip6tables, arptables, ebtables 等&#xff0c;统称为 xtables&#xff09;架构。nftables 提供了更强大、更灵活以及更易于管理的规则集配置方式&#xff0c;使得…

【java计算机毕设】办公用品管理系统MySQL ssm JSP maven项目设计代码源码+文档 前后端一体

1项目功能 【java计算机毕设】办公用品管理系统MySQL ssm JSP maven项目设计代码源码文档 前后端一体 2项目介绍 系统功能&#xff1a; 办公用品管理系统包括管理员、用户俩种角色。 管理员功能包括个人中心模块用于修改个人信息和密码、用户管理、用品分类管理、用品信息管理…

springcloud+vue项目,controller层接口返回json数据,前端可以接收到数据,但浏览器“F12-->网络-->响应“显示为空的问题处理

1.显示为空的场景 SharetekR(access_tokeneyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOiJQQzoxODA1ODA4ODc1MjUwMTIyNzUyIiwicm5TdHIiOiJrZEoxV05CV3NBSUdYb05TbktSU3kzOGNuSnk3c3FRTSIsInVzZXJJZCI6MTgwNTgwODg3NTI1MDEyMjc1MiwidXNlck5h…

grpc-go客户端接口添加

【1】 proto相关文件同服务端&#xff0c;如已经生成&#xff0c;可以直接使用服务端的文件&#xff08;包&#xff09; 【2】新建一个目录“WHG_CLIENT”&#xff0c;目录下新建一个main.go文件 package mainimport ("context""log""grpc-go-maste…

Kafka系列之SpringBoot集成Kafka

本文介绍如何在springboot项目中集成kafka收发message。 pom依赖 springboot相关的依赖我们就不提了&#xff0c;和kafka相关的只依赖一个spring-kafka集成包 <dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka<…

STM32F1+HAL库+FreeTOTS学习5——内核中断管理及中断控制函数

STM32F1HAL库FreeTOTS学习5——中断管理和临界段代码保护 中断简介中断优先级寄存器拓展FreeRTOS中PendSV和Systick中断优先级配置三个中断屏蔽寄存器FreeRTOS中断管理函数代码验证 上一期我们学习了FreeRTOS中任务挂起与恢复&#xff0c;在中断服务程序中恢复任务过程中&#…

[Redis]哨兵机制

哨兵机制概念 在传统主从复制机制中&#xff0c;会存在一些问题&#xff1a; 1. 主节点发生故障时&#xff0c;进行主备切换的过程是复杂的&#xff0c;需要人工参与&#xff0c;导致故障恢复时间无法保障。 2. 主节点可以将读压力分散出去&#xff0c;但写压力/存储压力是无法…

印章谁在管、谁用了、用在哪?契约锁让您打开手机一看便知

“印章都交给谁在管”、“哪些人能用”、“都有哪些业务在用”…这些既是管理者最关心的印章问题也是影响印章安全的关键要素。但是公司旗下分子公司那么多&#xff0c;各类公章、法人章、财务章、合同章一大堆&#xff0c;想“问”明白很难。 契约锁电子签及印控平台推出“印章…

14-11 2024 年的 13 个 AI 趋势

2024 年的 13 个 AI 趋势 人工智能对环境的影响和平人工智能人工智能支持的问题解决和决策针对人工智能公司的诉讼2024 年美国总统大选与人工智能威胁人工智能、网络犯罪和社会工程威胁人工智能治疗孤独与对人工智能的情感依赖人工智能影响者中国争夺人工智能霸主地位人工智能…

一句话回答的前端面试题

该篇文章为一句话的答案&#xff0c;想看更详细的面试题请看这篇>《前端面试题》 原型链&#xff1a; 实例与原型的链条&#xff0c;原型是prototype&#xff0c;链是__proto__&#xff0c;每个函数有一个原型对象&#xff0c;函数在创建时有一个默认属性 prototype&#x…