【SpringBoot】Redisson 分布式鎖注解和 @Transactional 注解一起使用問題

一、前言

平時使用切面去加分布式鎖,是先開啟事務還是先嘗試獲得鎖?這兩者有啥區別?

業務中怎么控制切面的順序?切面的順序對事務的影響怎么避免?

下面程序分析:

    @Override@Transactionalpublic ReceiveH5ActivityPrizeResponse receive(ReceiveH5ActivityPrizeRequest request) {logger.info("xxx:{}", JSON.toJSONString(request));ReceiveH5ActivityPrizeResponse response=new ReceiveH5ActivityPrizeResponse();String lockName="receiveH5ActivityPrize" + request.getActivityId();final DistributeLock lock = jedisLockFactory.getJedisLock(lockName,20, TimeUnit.SECONDS);// 1.加鎖lock.lock();try {//todo // 2 業務邏輯 先判斷是否存在,不存在插入一條數據,存在返回(不插入)} finally {// 3.釋放鎖lock.unLock();}// 4 返回return response;}

分布式鎖失效并不是真正的失效,只是讀到數據,讀取的數據庫數據不是最新的。

@Transactional 注解在執行該方法時開啟一個事物,當執行到3步時,insert 事物務還未提交,因此其它線程進入分布式鎖代碼塊后,繼續會執行2操作,發現數據不存在繼續插入一條新數據,存在兩條記錄,此時數據就會出現 bug 問題。

解決辦法:先加鎖,然后在開啟事物,可以保證安全性。?

二、普通未指定 order 的切面和 @Transactional 的先后順序

????????先說下為啥會考慮到這個,我們可以知道 @Transaction 一般加在具體要執行業務的service 方法上,那如果我要進行并發控制對業務進行加鎖,那么嘗試鎖和開啟事務孰先孰后呢?

    @Override@Transactional@RedisLock(key = Constant.FANLI_GRANT_VIP_LOCK, param = "#vipOrderNo")public void grantGdVip(String vipOrderNo) {// 業務邏輯}

????????按照業務流程上來看我們需要先嘗試鎖后開啟事務,因為沒獲得鎖開啟事務需要和數據庫進行交互開啟一個新的事務,平常對業務結果是不會影響的,但是當高并發時是會對數據庫帶來不小壓力。

總結:

????????如果普通切面沒指定 order 會比 transaction 后執行。當鎖或者一些檢查性切面被使用時如果條件不滿足不能進入業務也會導致事務的開啟產生了不必要的消耗,當并發高時尤為明顯。

三、切面的順序對事務的影響怎么避免?

其實避免方式有三種,一種是指定order,一種是把自定義切面移到更外層中,一種是使用編程式事務。

1、指定 Order

@Aspect
@Component
@Slf4j
@Order(1)
public class LockAspect {}

2、移到最外層中

移到更外層中就不用證明了,調用的自然順序,比如放在Controller的方法上。

    @PostMapping("/web/cardb/gift/receive")@ApiOperation("B卡贈品領取接口")@TokenAuthentication@RedisLock(key = LockKey.RECEIVE_CARD_B_GIFT, param = "#userInfo.userId")public ApiResultResponse receiveCardBGift(@RequestBody @Valid CardbReceiveGiftRequest request) {// 代碼
}

3、使用編程式事務

?當然可以,調用的自然順序,事務的開啟更加現式。

四、總結

因為聲明式事務比較好用,生產中使用的比較多,只有為了控制事務粒度或者不需要抽出一個新的類(為了使事務生效)才會使用編程式事務。

所以更加傾向于移到更外層,因為指定 order 的前提是你知道事務切面的和不指定order普通切面的順序,同時一旦切面變多比如有統一加鎖切面、統一檢查是否認證切面等需要控制自定義切面順序容易和事務切面搞混,不利于維護,這個也相當于自定義切面和框架前面隔離。這也從一個側面證明了校驗放 controller 的合理性。

五、參考文檔

@Transactional和普通自定義切面執行順序的思考

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/162822.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/162822.shtml
英文地址,請注明出處:http://en.pswp.cn/news/162822.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

uni-app - 彈出框

目錄 1.基本介紹 2.原生uinapp 通過uni.showActionSheet實現 3.使用組件 Popup 彈出層 ③效果展示 1.基本介紹 彈出框讓我們在需要時在屏幕底部彈出一個菜單,它通常用于在各種應用程序中進行選擇操作。Uniapp為我們提供了基本的底部彈出框組件,但它也有…

OpenSearch開發環境安裝Docker和Docker-Compose兩種方式

文章目錄 簡介常用請求創建映射寫入數據查詢數據其他 安裝Docker方式安裝OpenSearch安裝OpenSearchDashboard Docker-Compose方式Docker-Compose安裝1.設置主機環境2.下載docker-compose.yml文件3.啟動docker-compose4.驗證 問題問題1:IPv4 forwarding is disabled.…

如何搭建Zblog網站并通過內網穿透將個人博客發布到公網

文章目錄 1. 前言2. Z-blog網站搭建2.1 XAMPP環境設置2.2 Z-blog安裝2.3 Z-blog網頁測試2.4 Cpolar安裝和注冊 3. 本地網頁發布3.1. Cpolar云端設置3.2 Cpolar本地設置 4. 公網訪問測試5. 結語 1. 前言 想要成為一個合格的技術宅或程序員,自己搭建網站制作網頁是繞…

Altium Designer學習筆記11

畫一個LED的封裝: 使用這個SMD5050的封裝。 我們先看下這個芯片的功能說明: 5050貼片式發光二極管: XL-5050 是單線傳輸的三通道LED驅動控制芯片,采用的是單極性歸零碼協議。 數據再生模塊的功能,自動將級聯輸出的數…

CSGO搬磚干貨,全網最詳細教學!

CSGO游戲搬磚全套操作流程及注意事項(第一課) 在電競游戲中,CSGO(Counter-Strike: Global Offensive)被廣大玩家譽為經典之作。然而,除了在游戲中展現個人實力和團隊合作外,有些玩家還將CSGO作為…

Java之API(上)

前言: 這一次內容主要是圍繞Java開發中的一些常用類,然后主要是去學習這些類里面的方法。 一、高級API: (1)介紹:API指的是應用程序編程接口,API可以讓編程變得更加方便簡單。Java也提供了大量API供程序開發者使用&…

如何使用Google My Business來提升您的內容和SEO?

如果您的企業有實體店,那么使用Google My Business(GMB)來改善您的本地SEO并增強您的在線形象至關重要。Google My Business (GMB) 是 Google 提供的補充工具,使企業能夠控制其在 Google 搜索和地圖上的數字…

大數據基礎設施搭建 - Flume

文章目錄 一、上傳壓縮包二、解壓壓縮包三、監控本地文件(file to kafka)3.1 編寫配置文件3.2 自定義攔截器3.2.1 開發攔截器jar包(1)創建maven項目(2)開發攔截器類(3)開發pom文件&a…

【數字化轉型方法論讀書筆記】-數據中臺角色解讀

一千個讀者,就有一千個哈姆雷特。同樣,數據中臺對于企業內部不同角色的價值也不同,下面分別從董事長、CEO、 CTO/CIO、IT 架構師、數據分析師這 5 個角色的視角詳細解讀數據中臺。 1、董事長視角下的數據中臺 在數字經濟時代,企業…

RTT打印在分區跳轉后無法打印問題

場景: RTT打印僅占用JLINK的帶寬,比串口傳輸更快更簡潔,同時RTT可以使用jscope對代碼里面的變量實時繪圖顯示波形,而采用串口打印波形無法實時打印。同時可以保存原始數據到本地進行分析,RTT在各方面完勝串口。 問題描…

PTA-城市間緊急救援

作為一個城市的應急救援隊伍的負責人,你有一張特殊的全國地圖。在地圖上顯示有多個分散的城市和一些連接城市的快速道路。每個城市的救援隊數量和每一條連接兩個城市的快速道路長度都標在地圖上。當其他城市有緊急求助電話給你的時候,你的任務是帶領你的…

采樣概率 假設檢驗推導數組最大值的方法與可行性

當需要尋找大量數據中的最大值的時候,比如從 2G 個 float16 中尋找其中的最大值,是一件耗時的操作。 現計劃通過小樣本來發掘數據的規律,對最大值進行預測。 方案: step1,從2G個float16 中截取64段float16&#xff…

【Vue入門篇】基礎篇—Vue指令,Vue生命周期

🎊專欄【JavaSE】 🍔喜歡的詩句:更喜岷山千里雪 三軍過后盡開顏。 🎆音樂分享【如愿】 🎄歡迎并且感謝大家指出小吉的問題🥰 文章目錄 🍔Vue概述🎄快速入門🌺Vue指令?v-…

AI繪畫工具匯總:免費、簡單易上手

歡迎來到魔法寶庫,傳遞AIGC的前沿知識,做有格調的分享? 喜歡的話記得點個關注吧! 提到AI繪畫,許多人通常會想到Midjourney和Stable Diffusion等工具,然而,這些工具對于新手而言門檻較高,不太友…

【C++】——標準模板庫STL作業(其一)

🎃個人專欄: 🐬 算法設計與分析:算法設計與分析_IT閆的博客-CSDN博客 🐳Java基礎:Java基礎_IT閆的博客-CSDN博客 🐋c語言:c語言_IT閆的博客-CSDN博客 🐟MySQL&#xff1a…

opencv使用pyinstaller打包錯誤:‘can‘t find starting number (in the name of file)

使用Python語言和opencv模塊在pycharm中編輯的代碼運行沒問題,但是在使用pyinstaller打包后出現錯誤can‘t find starting number (in the name of file) [ERROR:0] global C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-q3d_8t8e\opencv\modules\videoi…

安卓畢業設計基于安卓android微信小程序的家校通系統

運行環境 開發語言:Java 框架:ssm JDK版本:JDK1.8 服務器:tomcat7 小程序框架:uniapp 小程序開發軟件:HBuilder X 小程序運行軟件:微信開發者 項目介紹 基于微信小程序的家校通系統的設計基…

【實用】PPT沒幾頁內存很大怎么解決

PPT頁數很少但導出內存很大解決方法 1.打開ppt點擊左上角 “文件”—“選項” 2.對話框選擇 “常規與保存” (1)如果想要文件特別小時可 取消勾選 “將字體嵌入文件” (2)文件大小適中 可選擇第一個選項 “僅最入文檔中所用的字…

每日一題 1410. HTML 實體解析器(中等,模擬)

模擬&#xff0c;沒什么好說的 class Solution:def entityParser(self, text: str) -> str:entityMap {&quot;: ",&apos;: "",>: >,<: <,&frasl;: /,&amp;: &,}i 0n len(text)res []while i < n:isEntity Falseif …

Oracle-客戶端連接報錯ORA-12545問題

問題背景: 用戶在客戶端服務器通過sqlplus通過scan ip登陸訪問數據庫時&#xff0c;偶爾會出現連接報錯ORA-12545: Connect failed because target host or object does not exist的情況。 問題分析&#xff1a; 首先&#xff0c;登陸到連接有問題的客戶端數據庫上&#xff0c;…