Spring TransactionTemplate 程式化交易管理與 Rollback
當初一開始用 Spring,習慣只會 @Transactional 這招。後來才發現 TransactionTemplate 這東西,發現它在某些場景真的有夠方便。
@Transactional 的限制
@Transactional 很直觀啦,加一個 annotation 就搞定交易管理。但踩坑的地方是:
- Proxy 限制 - 同個 class 內部呼叫不會觸發 proxy,交易會爆掉
- 粒度問題 - 整個方法才是一個交易,沒辦法在同一個方法裡控制多段獨立的交易
- Rollback 控制 - 用 rollbackFor 有點硬,不能細粒度決定要不要 rollback
TransactionTemplate 的救世主角色
TransactionTemplate 提供了「程式化」的交易控制。不用 annotation,直接寫程式邏輯,搭配 callback 來執行。
基本用法
首先注入 PlatformTransactionManager:
1 |
|
細粒度控制 Rollback
TransactionTemplate 最威的地方就是可以在交易中途決定要不要 rollback:
1 | public void complexTransition() { |
如果呼叫 status.setRollbackOnly(),即使沒有拋 exception,交易也會 rollback。這招對於「執行某些操作失敗但不想拋 exception」的場景真的很好用。
同一個方法裡多個獨立交易
這是 TransactionTemplate 超猛的地方。用 @Transactional 無法做到的事:
1 | public void processBatch() { |
這樣做的好處是,即使某個 item 處理失敗,後面的 item 還是能繼續處理。用 @Transactional 的話,第一個失敗整個方法都得 rollback。
設定交易隔離等級
TransactionTemplate 也支援設定隔離等級:
1 |
|
跟 @Transactional 的差別比較
| 項目 | @Transactional | TransactionTemplate |
|---|---|---|
| 使用難度 | 簡單,加 annotation | 稍複雜,要寫 callback |
| 同方法多交易 | 不支援 | 支援 |
| Proxy 限制 | 有(內部呼叫失效) | 沒有 |
| 細粒度控制 | 差(只能 rollbackFor) | 好(status.setRollbackOnly) |
| 效能 | 有 overhead | 稍好 |
實務建議
- 簡單情況 → 用 @Transactional,快速又清爽
- 複雜邏輯 → 用 TransactionTemplate,控制力強
- 混合使用 → 可以同時用兩個,但要避免嵌套的 proxy 問題
TransactionTemplate 初看有點繁瑣,但用過幾次就會覺得超香。特別是要處理批次資料或複雜的交易流程時,這招真的能救你一命。
本部落格所有文章除特別聲明外,均採用CC BY-NC-SA 4.0 授權協議。轉載請註明來源 Cheng's Tech & Life!
評論









