AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

Spring事務長了個腿?輕松掌握技巧告別長事務煩惱!

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

大家好,我是飄渺。今天繼續DDD&微服務專欄。hBc28資訊網——每日最新資訊28at.com

在之前的文章 基于DDD的訂單創建 流程中,我們留下了一個問題:在createOrder()方法中,我將調用遠程接口獲取購物車詳情、遠程庫存校驗、訂單保存放在一個事務中,顯然這并不是一個正確的做法,因為它會導致長事務,今天就讓我們來解決這個問題。hBc28資訊網——每日最新資訊28at.com

圖片圖片hBc28資訊網——每日最新資訊28at.com

為什么會產生長事務

首先,讓我們來分析一下產生長事務的原因。hBc28資訊網——每日最新資訊28at.com

在Spring中,@Transactional注解是基于AOP實現的,本質上是在目標方法執行前后進行攔截。在目標方法執行前加入或創建一個事務,在方法執行后,根據實際情況選擇提交或回滾事務。hBc28資訊網——每日最新資訊28at.com

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

在開頭的實例中,一個事務中執行RPC操作是典型的長事務問題。類似的操作還包括在事務中進行大量數據查詢、業務規則處理等。hBc28資訊網——每日最新資訊28at.com

長事務會產生哪些問題

長事務引發的常見危害有:hBc28資訊網——每日最新資訊28at.com

  1. 數據庫連接池被占滿,應用無法獲取連接資源;
  2. 容易引發數據庫死鎖;
  3. 數據庫回滾時間長;
  4. 在主從架構中會導致主從延時變大。

如何避免長事務

既然知道了長事務的危害,那么在開發中如何避免這個問題呢?hBc28資訊網——每日最新資訊28at.com

很明顯,解決長事務的宗旨就是 對事務方法進行拆分,盡量讓事務變小,變快,減小事務的顆粒度。hBc28資訊網——每日最新資訊28at.com

編程式事務

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

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

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

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

對方法進行拆分

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

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

在上述代碼中,獲取購物車詳情與庫存校驗不需要事務,將其與事務方法saveOrder()分開。然而,這樣的簡單拆分會導致事務不生效。這又涉及到另一個知識點:hBc28資訊網——每日最新資訊28at.com

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

  • @Transactional 應用在非 public 修飾的方法上
  • @Transactional 注解屬性 propagation 設置錯誤
  • @Transactional 注解屬性 rollbackFor 設置錯誤
  • 同一個類中方法調用,導致@Transactional失效
  • 異常被catch捕獲導致@Transactional失效

正確的拆分方法應該使用下面兩種:hBc28資訊網——每日最新資訊28at.com

  1. 將方法放入另一個類,如新增一個Manager層,通過Spring注入,這樣符合了在對象之間調用的條件。詳細說明可以參考我的文章為什么阿里建議給MVC三層架構再加一層Manager層!。
  2. 啟動類添加@EnableAspectJAutoProxy(exposeProxy = true),方法內使用AopContext.currentProxy()獲得代理類,使用事務。
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項目是基于DDD的分層架構模型實現。原來的業務邏輯是在應用服務編寫,在我們項目中只需要將保存訂單的邏輯放在領域服務層,由領域服務保證事務,而應用服務層負責組裝業務邏輯。最終代碼如下:hBc28資訊網——每日最新資訊28at.com

private final TradeOrderService tradeOrderService;@Override  // @Transactional(rollbackFor = RuntimeException.class)  public String createOrder(OrderCreateRequest orderCreateRequest) {      // 生成訂單編號      String orderSn = IdUtils.nextIdStr();      // 獲取購物車詳情      ShoppingCartDetailDTO shoppingCartDetailDTO = cartRemoteFacade.queryCheckedCartItemByUserId(orderCreateRequest.getCustomerId());      List<CartItemDTO> cartItemList = shoppingCartDetailDTO.getCartItemDtoS();            // 校驗庫存      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));      }}

小結

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

本文鏈接:http://www.tebozhan.com/showinfo-26-55265-0.htmlSpring事務長了個腿?輕松掌握技巧告別長事務煩惱!

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 淺談ArkUI之Web組件的基礎用法

下一篇: Spring事務長了個腿?輕松掌握技巧告別長事務煩惱!

標簽:
  • 熱門焦點
  • 鴻蒙OS 4.0公測機型公布:甚至連nova6都支持

    華為全新的HarmonyOS 4.0操作系統將于今天下午正式登場,官方在發布會之前也已經正式給出了可升級的機型產品,這意味著這些機型會率先支持升級享用。這次的HarmonyOS 4.0支持
  • 從 Pulsar Client 的原理到它的監控面板

    背景前段時間業務團隊偶爾會碰到一些 Pulsar 使用的問題,比如消息阻塞不消費了、生產者消息發送緩慢等各種問題。雖然我們有個監控頁面可以根據 topic 維度查看他的發送狀態,
  • 如何正確使用:Has和:Nth-Last-Child

    我們可以用CSS檢查,以了解一組元素的數量是否小于或等于一個數字。例如,一個擁有三個或更多子項的grid。你可能會想,為什么需要這樣做呢?在某些情況下,一個組件或一個布局可能會
  • 十個簡單但很有用的Python裝飾器

    裝飾器(Decorators)是Python中一種強大而靈活的功能,用于修改或增強函數或類的行為。裝飾器本質上是一個函數,它接受另一個函數或類作為參數,并返回一個新的函數或類。它們通常用
  • 讓我們一起聊聊文件的操作

    文件【1】文件是什么?文件是保存數據的地方,是數據源的一種,比如大家經常使用的word文檔、txt文件、excel文件、jpg文件...都是文件。文件最主要的作用就是保存數據,它既可以保
  • 從零到英雄:高并發與性能優化的神奇之旅

    作者 | 波哥審校 | 重樓作為公司的架構師或者程序員,你是否曾經為公司的系統在面對高并發和性能瓶頸時感到手足無措或者焦頭爛額呢?筆者在出道那會為此是吃盡了苦頭的,不過也得
  • 2299元起!iQOO Pad明晚首銷:性能最強天璣平板

    5月23日,iQOO如期舉行了新品發布會,除了首發安卓最強旗艦處理器的iQOO Neo8系列新機外,還在發布會上推出了旗下首款平板電腦——iQOO Pad,其最大的賣點
  • 回歸OPPO兩年,一加贏了銷量,輸了品牌

    成為OPPO旗下主打性能的先鋒品牌后,一加屢創佳績。今年618期間,一加手機全渠道銷量同比增長362%,憑借一加 11、一加 Ace 2、一加 Ace 2V三款爆品,一加
  • 機構稱Q2全球智能手機出貨量同比下滑11% 蘋果份額依舊第2

    7月20日消息,據外媒報道,研究機構的報告顯示,由于需求下滑,今年二季度全球智能手機的出貨量,同比下滑了11%,三星、蘋果等主要廠商的銷量,較去年同期均有下
Top