日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

Spring事務(wù)長了個(gè)腿?輕松掌握技巧告別長事務(wù)煩惱!

來源: 責(zé)編: 時(shí)間:2024-01-02 09:31:37 188觀看
導(dǎo)讀大家好,我是飄渺。今天繼續(xù)DDD&微服務(wù)專欄。在之前的文章 基于DDD的訂單創(chuàng)建 流程中,我們留下了一個(gè)問題:在createOrder()方法中,我將調(diào)用遠(yuǎn)程接口獲取購物車詳情、遠(yuǎn)程庫存校驗(yàn)、訂單保存放在一個(gè)事務(wù)中,顯然這并不是一個(gè)

大家好,我是飄渺。今天繼續(xù)DDD&微服務(wù)專欄。2cq28資訊網(wǎng)——每日最新資訊28at.com

在之前的文章 基于DDD的訂單創(chuàng)建 流程中,我們留下了一個(gè)問題:在createOrder()方法中,我將調(diào)用遠(yuǎn)程接口獲取購物車詳情、遠(yuǎn)程庫存校驗(yàn)、訂單保存放在一個(gè)事務(wù)中,顯然這并不是一個(gè)正確的做法,因?yàn)樗鼤?huì)導(dǎo)致長事務(wù),今天就讓我們來解決這個(gè)問題。2cq28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片2cq28資訊網(wǎng)——每日最新資訊28at.com

為什么會(huì)產(chǎn)生長事務(wù)

首先,讓我們來分析一下產(chǎn)生長事務(wù)的原因。2cq28資訊網(wǎng)——每日最新資訊28at.com

在Spring中,@Transactional注解是基于AOP實(shí)現(xiàn)的,本質(zhì)上是在目標(biāo)方法執(zhí)行前后進(jìn)行攔截。在目標(biāo)方法執(zhí)行前加入或創(chuàng)建一個(gè)事務(wù),在方法執(zhí)行后,根據(jù)實(shí)際情況選擇提交或回滾事務(wù)。2cq28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)Spring遇到該注解時(shí),會(huì)自動(dòng)從數(shù)據(jù)庫連接池中獲取連接并開啟事務(wù),然后綁定到ThreadLocal上,對于@Transactional注解包裹的整個(gè)方法都是使用同一個(gè)連接。如果出現(xiàn)耗時(shí)的操作,如第三方接口調(diào)用、業(yè)務(wù)邏輯復(fù)雜、大批量數(shù)據(jù)處理等,就會(huì)導(dǎo)致占用連接的時(shí)間很長,數(shù)據(jù)庫連接一直被占用不釋放。一旦類似操作過多,就會(huì)導(dǎo)致數(shù)據(jù)庫連接池耗盡。2cq28資訊網(wǎng)——每日最新資訊28at.com

在開頭的實(shí)例中,一個(gè)事務(wù)中執(zhí)行RPC操作是典型的長事務(wù)問題。類似的操作還包括在事務(wù)中進(jìn)行大量數(shù)據(jù)查詢、業(yè)務(wù)規(guī)則處理等。2cq28資訊網(wǎng)——每日最新資訊28at.com

長事務(wù)會(huì)產(chǎn)生哪些問題

長事務(wù)引發(fā)的常見危害有:2cq28資訊網(wǎng)——每日最新資訊28at.com

  1. 數(shù)據(jù)庫連接池被占滿,應(yīng)用無法獲取連接資源;
  2. 容易引發(fā)數(shù)據(jù)庫死鎖;
  3. 數(shù)據(jù)庫回滾時(shí)間長;
  4. 在主從架構(gòu)中會(huì)導(dǎo)致主從延時(shí)變大。

如何避免長事務(wù)

既然知道了長事務(wù)的危害,那么在開發(fā)中如何避免這個(gè)問題呢?2cq28資訊網(wǎng)——每日最新資訊28at.com

很明顯,解決長事務(wù)的宗旨就是 對事務(wù)方法進(jìn)行拆分,盡量讓事務(wù)變小,變快,減小事務(wù)的顆粒度。2cq28資訊網(wǎng)——每日最新資訊28at.com

編程式事務(wù)

因此,我們可以采用編程式事務(wù)替代聲明式事務(wù)@Transactional。在Spring項(xiàng)目中,可以注入TransactionTemplate對象,然后手動(dòng)控制事務(wù)范圍。改造過后的代碼如下所示:2cq28資訊網(wǎng)——每日最新資訊28at.com

public String createOrder(OrderCreateRequest orderCreateRequest) { // 獲取購物車詳情 ShoppingCartDetailDTO shoppingCartDetailDTO = cartRemoteFacade.queryCheckedCartItemByUserId(orderCreateRequest.getCustomerId()); List<CartItemDTO> cartItemList = shoppingCartDetailDTO.getCartItemDtoS(); //校驗(yàn)庫存 checkInventory(cartItemList); ...  transactionTemplate.executeWithoutResult(status -> {       orderRepository.save(tradeOrder);  eventPublisher.publishEvent(new OrderCreatedEvent(tradeOrder));  }); return orderSn;}

然而,這里涉及到另一個(gè)問題:在保存訂單后我們通過EventPublisher發(fā)布了一個(gè)事件,讓監(jiān)聽者來處理剩下的業(yè)務(wù)邏輯,(在Dailymart中創(chuàng)建訂單后需要進(jìn)行庫存預(yù)扣),在默認(rèn)情況下,Spring的事件監(jiān)聽機(jī)制是同步的將代碼進(jìn)行解耦,我們希望庫存扣減如果出現(xiàn)失敗需要回滾訂單,而編程式事務(wù)無法控制監(jiān)聽者的事務(wù)。因此,在這種場景下并不適合使用編程式事務(wù)來處理。2cq28資訊網(wǎng)——每日最新資訊28at.com

敲黑板:使用編程式事務(wù)替代聲明式事務(wù)是解決長事務(wù)最簡單的實(shí)現(xiàn)方式,在大部分場景下都可以采用。在使用時(shí)要注意編程式事務(wù)搭配EventPublisher時(shí)無法控制監(jiān)聽者的事務(wù)。2cq28資訊網(wǎng)——每日最新資訊28at.com

對方法進(jìn)行拆分

另外一種常見的處理措施就是將方法進(jìn)行拆分,將大方法拆成小方法,將不需要事務(wù)管理的邏輯與事務(wù)操作拆開。2cq28資訊網(wǎng)——每日最新資訊28at.com

public String createOrder(OrderCreateRequest orderCreateRequest) { // 獲取購物車詳情 ShoppingCartDetailDTO shoppingCartDetailDTO = cartRemoteFacade.queryCheckedCartItemByUserId(orderCreateRequest.getCustomerId()); List<CartItemDTO> cartItemList = shoppingCartDetailDTO.getCartItemDtoS(); //校驗(yàn)庫存 checkInventory(cartItemList); ...  this.saveOrder(tradeOrder) return orderSn;}@Transactional(rollbackFor = RuntimeException.class)private void saveOrder(TradeOrder tradeOrder){ orderRepository.save(tradeOrder); eventPublisher.publishEvent(new OrderCreatedEvent(tradeOrder)); }

在上述代碼中,獲取購物車詳情與庫存校驗(yàn)不需要事務(wù),將其與事務(wù)方法saveOrder()分開。然而,這樣的簡單拆分會(huì)導(dǎo)致事務(wù)不生效。這又涉及到另一個(gè)知識(shí)點(diǎn):2cq28資訊網(wǎng)——每日最新資訊28at.com

@Transactional注解的聲明式事務(wù)是通過spring aop起作用的,而spring aop需要生成代理對象,直接在同一個(gè)類中方法調(diào)用使用的還是原始對象,事務(wù)不生效。其他幾個(gè)常見的事務(wù)不生效的場景為:2cq28資訊網(wǎng)——每日最新資訊28at.com

  • @Transactional 應(yīng)用在非 public 修飾的方法上
  • @Transactional 注解屬性 propagation 設(shè)置錯(cuò)誤
  • @Transactional 注解屬性 rollbackFor 設(shè)置錯(cuò)誤
  • 同一個(gè)類中方法調(diào)用,導(dǎo)致@Transactional失效
  • 異常被catch捕獲導(dǎo)致@Transactional失效

正確的拆分方法應(yīng)該使用下面兩種:2cq28資訊網(wǎng)——每日最新資訊28at.com

  1. 將方法放入另一個(gè)類,如新增一個(gè)Manager層,通過Spring注入,這樣符合了在對象之間調(diào)用的條件。詳細(xì)說明可以參考我的文章為什么阿里建議給MVC三層架構(gòu)再加一層Manager層!。
  2. 啟動(dòng)類添加@EnableAspectJAutoProxy(exposeProxy = true),方法內(nèi)使用AopContext.currentProxy()獲得代理類,使用事務(wù)。
SpringBootApplication.java    @EnableAspectJAutoProxy(exposeProxy = true)  @SpringBootApplication  public class SpringBootApplication {}public String createOrder(OrderCreateRequest orderCreateRequest) { ... OrderService orderService = (OrderService)AopContext.currentProxy();     orderService.saveData(tradeOrder);   return orderSn;}@Transactional(rollbackFor = RuntimeException.class)private void saveOrder(TradeOrder tradeOrder){ orderRepository.save(tradeOrder); eventPublisher.publishEvent(new OrderCreatedEvent(tradeOrder)); }

然而,Dailymart項(xiàng)目是基于DDD的分層架構(gòu)模型實(shí)現(xiàn)。原來的業(yè)務(wù)邏輯是在應(yīng)用服務(wù)編寫,在我們項(xiàng)目中只需要將保存訂單的邏輯放在領(lǐng)域服務(wù)層,由領(lǐng)域服務(wù)保證事務(wù),而應(yīng)用服務(wù)層負(fù)責(zé)組裝業(yè)務(wù)邏輯。最終代碼如下:2cq28資訊網(wǎng)——每日最新資訊28at.com

private final TradeOrderService tradeOrderService;@Override  // @Transactional(rollbackFor = RuntimeException.class)  public String createOrder(OrderCreateRequest orderCreateRequest) {      // 生成訂單編號(hào)      String orderSn = IdUtils.nextIdStr();      // 獲取購物車詳情      ShoppingCartDetailDTO shoppingCartDetailDTO = cartRemoteFacade.queryCheckedCartItemByUserId(orderCreateRequest.getCustomerId());      List<CartItemDTO> cartItemList = shoppingCartDetailDTO.getCartItemDtoS();            // 校驗(yàn)庫存      checkInventory(cartItemList);   ...          tradeOrderService.save(tradeOrder);     return orderSn;  }@Service  @RequiredArgsConstructor(onConstructor = @__(@Autowired))  public class TradeOrderServiceImpl implements TradeOrderService {            private final ApplicationEventPublisher eventPublisher;            private final OrderRepository orderRepository;            @Override      @Transactional        public void save(TradeOrder tradeOrder) {          orderRepository.save(tradeOrder);          eventPublisher.publishEvent(new OrderCreatedEvent(tradeOrder));      }}

小結(jié)

本文討論了長事務(wù)的危害及解決方案。首先,我們探討了長事務(wù)導(dǎo)致的問題,包括數(shù)據(jù)庫連接池耗盡、死鎖等。其次,介紹了兩種解決策略:采用編程式事務(wù)和對方法進(jìn)行拆分。編程式事務(wù)提供了手動(dòng)控制事務(wù)范圍的方式,但需要注意搭配EventPublisher可能導(dǎo)致監(jiān)聽者事務(wù)無法控制的問題。對方法進(jìn)行拆分是一種更通用的方法,能夠減小事務(wù)范圍,提高執(zhí)行效率。最后,通過實(shí)際的DDD分層架構(gòu)示例,展示了在應(yīng)用服務(wù)層和領(lǐng)域服務(wù)層中如何組織業(yè)務(wù)邏輯,確保事務(wù)正確性和性能。2cq28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-55266-0.htmlSpring事務(wù)長了個(gè)腿?輕松掌握技巧告別長事務(wù)煩惱!

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: Spring事務(wù)長了個(gè)腿?輕松掌握技巧告別長事務(wù)煩惱!

下一篇: ElasticSearch 的概念解析與使用方式

標(biāo)簽:
  • 熱門焦點(diǎn)
  • 紅魔電競平板評(píng)測:大屏幕硬實(shí)力

    前言:三年的疫情因?yàn)橐暇W(wǎng)課的原因激活了平板市場,如今網(wǎng)課的時(shí)代已經(jīng)過去,大家的生活都恢復(fù)到了正軌,這也就意味著,真正考驗(yàn)平板電腦生存的環(huán)境來了。也就是面對著這種殘酷的
  • Golang 中的 io 包詳解:組合接口

    io.ReadWriter// ReadWriter is the interface that groups the basic Read and Write methods.type ReadWriter interface { Reader Writer}是對Reader和Writer接口的組合,
  • 分布式系統(tǒng)中的CAP理論,面試必問,你理解了嘛?

    對于剛剛接觸分布式系統(tǒng)的小伙伴們來說,一提起分布式系統(tǒng),就感覺高大上,深不可測。而且看了很多書和視頻還是一臉懵逼。這篇文章主要使用大白話的方式,帶你理解一下分布式系統(tǒng)
  • 如何正確使用:Has和:Nth-Last-Child

    我們可以用CSS檢查,以了解一組元素的數(shù)量是否小于或等于一個(gè)數(shù)字。例如,一個(gè)擁有三個(gè)或更多子項(xiàng)的grid。你可能會(huì)想,為什么需要這樣做呢?在某些情況下,一個(gè)組件或一個(gè)布局可能會(huì)
  • 網(wǎng)紅炒股不為了賺錢,那就是耍流氓!

    來源:首席商業(yè)評(píng)論6月26日高調(diào)宣布入市,網(wǎng)絡(luò)名嘴大v胡錫進(jìn)居然進(jìn)軍了股市。在一次財(cái)經(jīng)媒體峰會(huì)上,幾個(gè)財(cái)經(jīng)圈媒體大佬就&ldquo;胡錫進(jìn)炒股是否知道認(rèn)真報(bào)道&rdquo;展開討論。有
  • 三星Galaxy Z Fold5今日亮相:厚度縮減但仍略顯厚重

    據(jù)官方此前宣布,三星將于7月26日也就是今天在韓國首爾舉辦Unpacked活動(dòng),屆時(shí)將帶來帶來包括Galaxy Buds 3、Galaxy Watch 6、Galaxy Tab S9、Galaxy
  • 2299元起!iQOO Pad明晚首銷:性能最強(qiáng)天璣平板

    5月23日,iQOO如期舉行了新品發(fā)布會(huì),除了首發(fā)安卓最強(qiáng)旗艦處理器的iQOO Neo8系列新機(jī)外,還在發(fā)布會(huì)上推出了旗下首款平板電腦——iQOO Pad,其最大的賣點(diǎn)
  • AI藝術(shù)欣賞體驗(yàn)會(huì)在上海梅賽德斯奔馳中心音樂俱樂部上演

    光影交錯(cuò)的鏡像世界,虛實(shí)幻化的視覺奇觀,虛擬偶像與真人共同主持,這些場景都出現(xiàn)在2019世界人工智能大會(huì)的舞臺(tái)上。8月29日至31日,“AI藝術(shù)欣賞體驗(yàn)會(huì)”在上海
  • 世界人工智能大會(huì)國際日開幕式活動(dòng)在世博展覽館開啟

    30日上午,世界人工智能大會(huì)國際日開幕式活動(dòng)在世博展覽館開啟,聚集國際城市代表、重量級(jí)院士專家、國際創(chuàng)新企業(yè)代表,共同打造人工智能交流平臺(tái)。上海市副市
Top 主站蜘蛛池模板: 阳高县| 霍山县| 科技| 佛学| 景德镇市| 修水县| 历史| 桑植县| 古交市| 淄博市| 台湾省| 云霄县| 西畴县| 虎林市| 昂仁县| 乌拉特后旗| 蓝山县| 遵化市| 阜平县| 永平县| 砚山县| 惠水县| 马山县| 万盛区| 大渡口区| 海林市| 迭部县| 白玉县| 临颍县| 镇赉县| 克什克腾旗| 浦城县| 江达县| 衡南县| 清流县| 玉树县| 大安市| 从化市| 乡城县| 巴青县| 琼海市|