常見迷思:「用 Spring 必須用事務管理器,否則無法持久化」。事實:DAO 完全可以在無事務環境下工作。 若 DataSource 設定 defaultAutoCommit=true(預設),每條 SQL 即時提交,數據正常入庫。關閉自動提交且無事務管理器時,數據不會提交,查詢不到結果。
結論: 事務管理器提供 ACID 保證,非持久化前提。純讀、高效能、不支援事務的資料庫(如 MyISAM)可完全省略事務配置。Hibernate 例外:其事務管理與一級快取綁定,建議始終配置 HibernateTransactionManager。
「Web-Service-DAO 三層必須拆分、必須定義介面」是過度設計。Spring 僅要求 POJO 成為 Bean(@Component 等),無任何分層與介面強制要求。
極簡示例: 單一類別同時擔任 Controller(@Controller + @RequestMapping)、Service(業務邏輯)、DAO(注入 JdbcTemplate 直連資料庫),配合 AOP 事務增強,完美運行。簡單才是硬道理。
迷思:「事務方法不能調用事務方法,否則產生多個事務」。錯誤源於不懂傳播行為。Spring 默認 PROPAGATION_REQUIRED:外層開啟事務,內層加入同一事務。實驗證明:UserService.logon() → updateLastLogonTime()(同類,無代理攔截,代碼內聯效果)→ ScoreService.addScore()(不同 Bean,日誌顯示 Participating in existing transaction)共用同一連線、同一事務。
七大傳播行為滿足各種業務場景,開發者無需為事務管理扭曲服務設計。
Spring Bean 默認單例,透過 ThreadLocal 將有狀態資源(Connection、Session)線程本地化,實現「無狀態單例」。單例 Bean 天然線程安全。
跨線程事務隔離: 事務上下文綁定於線程。主線程開啟事務 → 啟動子線程執行事務方法 → 子線程獨立開啟新事務,互不干擾。日誌顯示主線程提交後,子線程才獲取連線、提交。結論:相同線程共享事務,不同線程隔離事務。
下篇將深入混合持久化技術事務協作與 AOP 代理盲區。