日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringBoot - 优雅的处理【长事务】

發(fā)布時間:2025/3/21 javascript 60 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringBoot - 优雅的处理【长事务】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • Pre
  • What
  • How
    • 方法一 編程式事務
    • 使用@Transactional 又能避免產生長事務
      • 方法一
      • 方法二


Pre

SpringBoot - 實踐阿里巴巴【Manager 層_通用業(yè)務處理層】

在Spring體系中,在方法上加上注解@Transactional,Spring自動幫我們進行事務的開啟、提交、回滾操作,真的是太方便了,以至于不分青紅皂白,啥都搞上…


What

運行時間比較長,長時間未提交的事務,都可以稱之為長事務

長事務引發(fā)的常見危害有:

  • 數據庫連接池被占滿,應用無法獲取連接資源
  • 容易引發(fā)數據庫死鎖
  • 數據庫回滾時間長
  • 在主從架構中會導致主從延時變大 等等

How

原則: 對事務方法進行拆分,盡量讓事務變小,變快,減小事務的顆粒度

我們知道@Transactional注解進行事務管理的操作叫聲明式事務, 使用聲明式事務的優(yōu)點 很明顯,簡單,僅需要關注業(yè)務, Spring框架自動幫我們進行事務的開啟、提交以及回滾等操作。

聲明式事務有一個最大的缺點,就是事務的顆粒度是整個方法,無法進行精細化控制。

那 與聲明式事務對應的就是編程式事務 是不是可以解決 顆粒度的問題呢?

方法一 編程式事務

基于底層的API,開發(fā)者在代碼中手動的管理事務的開啟、提交、回滾等操作。

在spring項目中我們可以使用TransactionTemplate類的對象,手動控制事務。

@Autowired private TransactionTemplate transactionTemplate; ... public void save(ArtisanDto artisanDto) { transactionTemplate.execute(transactionStatus -> {artisanDao.save(artisanDto);//....// .....return Boolean.TRUE; }); }

使用編程式事務最大的好處就是可以精細化控制事務范圍, 所以避免長事務最簡單的方法就是不要使用聲明式事務@Transactional,而是使用編程式事務手動控制事務范圍。

使用@Transactional 又能避免產生長事務

那既想使用@Transactional 又想避免產生長事務呢?

那就需要對方法進行拆分,將不需要事務管理的邏輯與事務操作分開.

@Service public class ArtisanService{public void create(ArtisanDto dto){queryData();biz();save(dto);}//事務操作@Transactional(rollbackFor = Throwable.class)public void save(ArtisanDto dto){artisanDao.insert(dto);} }

queryData()與biz()不需要事務,我們將其與事務方法save()拆開.

這種拆分會命中使用@Transactional注解時事務不生效的經典場景. @Transactional注解的聲明式事務是通過spring aop起作用的,而spring aop需要生成代理對象,直接在同一個類中方法調用使用的還是原始對象,事務不生效。

其他幾個常見的事務不生效的場景為:

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

每日一博 - 常見的Spring事務失效&事務不回滾案例集錦

所以正確的拆分方法應該是下面兩種

方法一

可以將方法放入另一個類,如新增 manager層,通過spring注入,這樣符合了在對象之間調用的條件。

@Service public class ArtisanService{@Autowiredprivate ArtisanManager artisanManager;public void create(ArtisanDto dto){queryData();biz();artisanManager.save(dto);} } @Service public class ArtisanManager{@Autowiredprivate ArtisanDao artisanDao;@Transactional(rollbackFor = Throwable.class)public void save(ArtisanCreateDTO dto){artisanDao.saveData(dto);} }

參考 SpringBoot - 實踐阿里巴巴【Manager 層_通用業(yè)務處理層】

方法二

啟動類添加@EnableAspectJAutoProxy(exposeProxy = true),方法內使用AopContext.currentProxy()獲得代理類,使用事務。

@EnableAspectJAutoProxy(exposeProxy = true) @SpringBootApplication public class SpringBootApplication {} public void createArtisan(ArtisanCreateDTO dto){ArtisanService artisanService = (ArtisanService)AopContext.currentProxy();artisanService.saveData(dto); }


總結

以上是生活随笔為你收集整理的SpringBoot - 优雅的处理【长事务】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。