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

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

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

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

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

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

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

為什么會產生長事務

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

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

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

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

長事務會產生哪些問題

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

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

如何避免長事務

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

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

編程式事務

因此,我們可以采用編程式事務替代聲明式事務@Transactional。在Spring項目中,可以注入TransactionTemplate對象,然后手動控制事務范圍。改造過后的代碼如下所示:kaj28資訊網——每日最新資訊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的事件監聽機制是同步的將代碼進行解耦,我們希望庫存扣減如果出現失敗需要回滾訂單,而編程式事務無法控制監聽者的事務。因此,在這種場景下并不適合使用編程式事務來處理。kaj28資訊網——每日最新資訊28at.com

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

對方法進行拆分

另外一種常見的處理措施就是將方法進行拆分,將大方法拆成小方法,將不需要事務管理的邏輯與事務操作拆開。kaj28資訊網——每日最新資訊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()分開。然而,這樣的簡單拆分會導致事務不生效。這又涉及到另一個知識點:kaj28資訊網——每日最新資訊28at.com

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

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

正確的拆分方法應該使用下面兩種:kaj28資訊網——每日最新資訊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的分層架構模型實現。原來的業務邏輯是在應用服務編寫,在我們項目中只需要將保存訂單的邏輯放在領域服務層,由領域服務保證事務,而應用服務層負責組裝業務邏輯。最終代碼如下:kaj28資訊網——每日最新資訊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分層架構示例,展示了在應用服務層和領域服務層中如何組織業務邏輯,確保事務正確性和性能。kaj28資訊網——每日最新資訊28at.com

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

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

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

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

標簽:
  • 熱門焦點
  • 紅魔電競平板評測:大屏幕硬實力

    前言:三年的疫情因為要上網課的原因激活了平板市場,如今網課的時代已經過去,大家的生活都恢復到了正軌,這也就意味著,真正考驗平板電腦生存的環境來了。也就是面對著這種殘酷的
  • 5月安卓手機好評榜:魅族20 Pro奪冠

    性能榜和性價比榜之后,我們來看最后的安卓手機好評榜,數據來源安兔兔評測,收集時間2023年5月1日至5月31日,僅限國內市場。第一名:魅族20 Pro好評率:97.50%不得不感慨魅族老品牌還
  • 消息稱迪士尼要拍真人版《魔發奇緣》:女主可能也找黑人演員

    8月5日消息,迪士尼確實有點忙,忙著將不少動畫改成真人版,繼《美人魚》后,真人版《白雪公主》、《魔發奇緣》也在路上了。據外媒消息稱,迪士尼將打造真人版
  • 虛擬鍵盤 API 的妙用

    你是否在遇到過這樣的問題:移動設備上有一個固定元素,當激活虛擬鍵盤時,該元素被隱藏在了鍵盤下方?多年來,這一直是 Web 上的默認行為,在本文中,我們將探討這個問題、為什么會發生
  • 一文掌握 Golang 模糊測試(Fuzz Testing)

    模糊測試(Fuzz Testing)模糊測試(Fuzz Testing)是通過向目標系統提供非預期的輸入并監視異常結果來發現軟件漏洞的方法。可以用來發現應用程序、操作系統和網絡協議等中的漏洞或
  • 本地生活這塊肥肉,拼多多也想吃一口

    出品/壹覽商業 作者/李彥編輯/木魚拼多多也看上本地生活這塊蛋糕了。近期,拼多多在App首頁&ldquo;充值中心&rdquo;入口上線了本機生活界面。壹覽商業發現,該界面目前主要
  • 大廠卷向扁平化

    來源:新熵作者丨南枝 編輯丨月見大廠職級不香了。俗話說,兵無常勢,水無常形,互聯網企業調整職級體系并不稀奇。7月13日,淘寶天貓集團啟動了近年來最大的人力制度改革,目前已形成一
  • 電博會上海爾智家模擬500平大平層,還原生活空間沉浸式體驗

    電博會為了更好地讓參展觀眾真正感受到智能家居的絕妙之處,海爾智家的程傳嶺先生同樣介紹了展會上海爾智家的模擬500平大平層,還原生活空間沉浸式體驗。程傳
  • 親歷馬斯克血洗Twitter,硅谷的苦日子在后頭

    文/劉哲銘  編輯/李薇  馬斯克再次揮下裁員大刀。  美國時間11月14日,Twitter約4400名外包員工遭解雇,此次被解雇的員工的主要工作為內容審核等。此前,T
Top 主站蜘蛛池模板: 衡东县| 东丽区| 湛江市| 宿松县| 二手房| 临城县| 衡东县| 广饶县| 沾益县| 湟中县| 临澧县| 齐河县| 视频| 西城区| 屏东市| 桐庐县| 平罗县| 绩溪县| 化州市| 沐川县| 宜州市| 吉隆县| 合山市| 万全县| 五莲县| 通辽市| 望谟县| 石景山区| 县级市| 上饶县| 利津县| 丰宁| 利川市| 永德县| 宁化县| 永嘉县| 化德县| 汉川市| 繁峙县| 政和县| 鹰潭市|