定位線上同步鎖仍然重復扣費的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.pswp.cn/web/40035.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/40035.shtml
英文地址,請注明出處:http://en.pswp.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…