@Transactional 是 Spring AOP 代理,幫助自動管理數(shù)據(jù)庫事務
必須 public、
必須由 Spring 代理調用(不能本類內(nèi)部調用)
異常必須拋出去,不能被 try-catch 吞掉
類必須被 Spring 管理(@Service/@Component)
實際開發(fā)統(tǒng)一配 rollbackFor = Exception.class
傳播機制默認 REQUIRED 足夠,日志類用 REQUIRES_NEW
一、基本用法
- 加在哪里?
優(yōu)先加在 業(yè)務層方法 / 類上
不要加在 Controller、Mapper 上
@Service
public class OrderService {
@Transactional
public void createOrder() {
// 多個 DB 操作
orderMapper.insert(...);
stockMapper.updateStock(...);
}
}
- 作用
自動開啟事務
正常執(zhí)行 → commit
拋異常 → rollback
同一線程內(nèi)復用同一個數(shù)據(jù)庫連接
二、核心常用屬性
- rollbackFor:哪些異?;貪L(非常重要)
默認行為:
只對 RuntimeException 和 Error 回滾
受檢異常(Exception)不回滾
所以實際開發(fā)幾乎都要寫:
@Transactional(rollbackFor = Exception.class)
表示任何異常都回滾。
- noRollbackFor:哪些異常不回滾
@Transactional(rollbackFor = Exception.class,
noRollbackFor = BusinessWarnException.class)
- propagation:事務傳播行為
默認:Propagation.REQUIRED
常用 3 個
REQUIRED
有事務就加入,沒有就新建
業(yè)務 99% 用這個
REQUIRES_NEW
掛起當前事務,新建一個獨立事務
適用場景:日志、消息發(fā)送、失敗不影響主流程
NESTED
嵌套事務,基于數(shù)據(jù)庫 savepoint
內(nèi)層回滾只回滾到保存點,不影響外層 - isolation:事務隔離級別
默認:使用數(shù)據(jù)庫默認隔離級別
可選:
Isolation.DEFAULT
Isolation.READ_UNCOMMITTED
Isolation.READ_COMMITTED
Isolation.REPEATABLE_READ
Isolation.SERIALIZABLE
Oracle 默認:READ_COMMITTED
MySQL InnoDB 默認:REPEATABLE_READ
- timeout:事務超時(秒)
@Transactional(timeout = 10)
事務執(zhí)行超過 10 秒回滾。
- readOnly:只讀事務
@Transactional(readOnly = true)
優(yōu)化:不加鎖、不記錄 undo/redo
只查詢時建議開啟,性能更好
三、事務傳播機制舉例
- REQUIRED(默認)
A 有事務 → B 加入 A 事務
A 回滾 → B 一起回滾 - REQUIRES_NEW
A 調用 B
B 新建獨立事務
B 異常回滾,A 可以捕獲不回滾
A 回滾,不影響 B 已經(jīng)提交的內(nèi)容
適用:記錄操作日志、發(fā)送消息。 - NESTED
B 是 A 的嵌套事務
B 回滾 → 只回滾 B,A 可繼續(xù)
A 回滾 → B 一起回滾