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

歡迎訪問 生活随笔!

生活随笔

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

javascript

不要在 Spring Boot 集成测试中使用 @Transactional

發布時間:2025/7/14 javascript 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 不要在 Spring Boot 集成测试中使用 @Transactional 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在測試運行時,測試類中 @Transactional 注解,會導致測試中 Entity 數據的操作都是在內存中完成,最終并不會進行 commit 操作,也就是不會將 Entity 數據進行持久化操作,從而導致測試的行為和真實應用的行為不一致。

事務管理在應用開發中是種不可或缺的設計,它是數據庫持久化處理的一種標準。我們知道,應用程序開發離不開對數據的CRUD(增刪改查),事務的ACID性可以更好保證數據的完整性,保證相關數據的同生共死。單個事務生命周期主要分為三個階段,BEGIN TRANSACTION -> COMMIT TRANSACTION -> ROLLBACK TRANSACTION。

Spring Boot事務的使用分為命令式聲明式常用的方式是聲明式注解(@Transactional)。事務管理既可以在應用層使用,也可以在測試中使用。

為了保證測試之間的相互獨立,測試之間數據不會被相互影響。也許你寫過這樣的測試:

@SpringBootTest @ActiveProfiles("test") @Transactional public class UserControllerTest { }

@Transactional 通過將數據持久化操作截斷,來解決測試之間相互對立,數據相互不影響的問題。然而這樣方式會有副作用,就是數據持久化的過程不再真實,沒有了commit的過程。從而會導致:

  • 無法保證 Entity 之間關聯關系,唯一索引和主外鍵關聯的準確性
  • 無法保證 Entity 創建時間、更新時間和版本化(樂觀鎖)的賦值邏輯的準確性
  • 無法保證 Entity 中有 @Transient 注解的屬性的賦值邏輯的準確性
  • 測試的數據不是真實場景存在的問題
  • 測試中,單個事務中的準備數據,無法在多線程中共享。

......

然后 Spring 在測試問題域中引入事務管理初衷是什么?為了解決什么問題才需要將它引入?官方文檔介紹 Transaction management

按照官方文檔意思,為了解決測試運行時,程序訪問真實的數據庫,改變數據的狀態,從而影響到后續的測試問題。

其實這里應該批判性思維一下,為什么測試運行時,需要訪問真實的數據庫?為什么測試之間的數據會相互影響?
對于每個測試來說,每次運行前都應該有干凈的上下文,或者說獨立的上下文,有數據清理和準備的過程,測試與測試之間相互隔離。也就是說,為什么測試不能用內存數據庫或者嵌入式數據庫?為什么不是每個測試運行前清理一下數據庫中的數據,保證測試用例運行前的一方凈土,不被上個測試數據影響?

答案當然是,可以!!!

寫在最后

如何做?實現一個 TruncateDatabaseService,只刪除表的數據,不刪除表的結果。 在測試基類的@BeforeEach,執行 truncate。源碼Truncate Database:

TruncateDatabaseBasicOnHibernateService
TruncateDatabaseBasicOnMybatisService 原文鏈接

總結

以上是生活随笔為你收集整理的不要在 Spring Boot 集成测试中使用 @Transactional的全部內容,希望文章能夠幫你解決所遇到的問題。

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