文章目錄
- 前言
- 一、Spring 事務管理(Transaction Management)
- 1. 使用 @Transactional 管理事務
- 2. 核心屬性說明
- 3. 事務傳播行為詳解(Propagation)
- 4. 異常回滾策略分析
- 5. 底層原理剖析(源碼級)
- 二、Spring 事件機制(ApplicationEvent)
- 1.定義自定義事件類
- 2. 發布事件
- 3. 監聽事件(兩種方式)
- 4. 異步監聽事件
- 5. 控制事件監聽器優先級
- 避坑提醒:
- 總結
前言
在開發復雜的企業級系統時,Spring 框架的事務管理和事件機制是兩個不可或缺的核心模塊。本文將從實際開發出發,全面講解 Spring 的事務處理原理、事件發布-監聽機制,并深入剖析常被忽視但極其重要的細節:事務傳播行為、異常回滾策略與事件優先級控制,幫助你在關鍵業務場景中少踩坑,提升系統健壯性與可維護性。
一、Spring 事務管理(Transaction Management)
Spring 提供了聲明式和編程式兩種事務管理方式,聲明式事務結合注解與 AOP,更加簡潔、優雅。
1. 使用 @Transactional 管理事務
@Service
public class OrderService {@Transactionalpublic void createOrder() {// 插入訂單// 扣減庫存// 插入操作日志}
}
2. 核心屬性說明
屬性 | 含義 |
---|---|
propagation | 事務傳播行為(默認:REQUIRED) |
isolation | 事務隔離級別(如 READ_COMMITTED) |
rollbackFor | 指定哪些異常類型觸發回滾 |
readOnly | 是否只讀,適用于查詢優化 |
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.READ_COMMITTED,rollbackFor = Exception.class
)
3. 事務傳播行為詳解(Propagation)
Spring 定義了 7 種事務傳播行為,用于處理不同事務上下文嵌套關系:
類型 | 含義 |
---|---|
REQUIRED | 默認,存在事務則加入,否則新建 |
REQUIRES_NEW | 總是新建事務,掛起當前事務 |
NESTED | 嵌套事務,支持回滾到 Savepoint |
SUPPORTS | 有事務則加入,無則非事務執行 |
NOT_SUPPORTED | 永遠非事務,掛起當前事務 |
MANDATORY | 必須存在事務,否則拋異常 |
NEVER | 禁止事務,有事務就拋異常 |
@Transactional
public void methodA() {methodB(); // 默認 REQUIRED
}@Transactional(propagation = Propagation.REQUIRES_NEW)
public void methodB() {// 新事務
}
注意:REQUIRES_NEW 將暫停 methodA 的事務,獨立執行和提交/回滾 methodB。
4. 異常回滾策略分析
默認行為:
- 運行時異常(RuntimeException):自動回滾
- 受檢異常(Exception):默認不回滾,需手動指定
顯式配置:
@Transactional(rollbackFor = Exception.class)
public void method() throws Exception {throw new Exception("不會默認回滾,需配置 rollbackFor");
}
5. 底層原理剖析(源碼級)
Spring 聲明式事務的核心實現類為:
- TransactionInterceptor:事務切面攔截器
- PlatformTransactionManager:統一事務管理接口
- DataSourceTransactionManager:JDBC 實現
- TransactionAspectSupport:控制事務的實際邏輯
流程:
- 代理對象攔截方法調用;
- TransactionInterceptor.invoke() 判斷事務屬性;
- 調用 AbstractPlatformTransactionManager#getTransaction() 創建事務;
- 執行目標方法;
- 根據是否異常決定提交或回滾。
二、Spring 事件機制(ApplicationEvent)
Spring 內置發布-訂閱模型,可用于解耦系統模塊,處理異步或擴展性強的邏輯,如日志、通知、審計等。
1.定義自定義事件類
public class UserRegisteredEvent extends ApplicationEvent {private final String username;public UserRegisteredEvent(Object source, String username) {super(source);this.username = username;}public String getUsername() {return username;}
}
2. 發布事件
@Component
public class UserService {@Autowiredprivate ApplicationEventPublisher publisher;public void register(String username) {// 注冊業務邏輯publisher.publishEvent(new UserRegisteredEvent(this, username));}
}
3. 監聽事件(兩種方式)
方式一:實現接口 ApplicationListener
@Component
public class EmailNotifier implements ApplicationListener<UserRegisteredEvent> {public void onApplicationEvent(UserRegisteredEvent event) {System.out.println("發送歡迎郵件給:" + event.getUsername());}
}
方式二:注解方式 @EventListener
@Component
public class SmsNotifier {@EventListenerpublic void handle(UserRegisteredEvent event) {System.out.println("發送短信通知:" + event.getUsername());}
}
4. 異步監聽事件
@EnableAsync
@Configuration
public class AsyncConfig {// 配置線程池等
}
監聽器加 @Async:
@Async
@EventListener
public void asyncHandle(UserRegisteredEvent event) {// 異步通知
}
5. 控制事件監聽器優先級
多個監聽器響應同一事件時,可通過以下方式控制執行順序:
使用 @Order
@Order(1)
@EventListener
public void firstHandler(MyEvent event) {// 優先執行
}
實現 SmartApplicationListener
@Component
public class HighPriorityListener implements SmartApplicationListener {public int getOrder() {return 0;}public void onApplicationEvent(ApplicationEvent event) {// 最優先執行}public boolean supportsEventType(Class<?> eventType) {return eventType == MyEvent.class;}
}
底層通過 AnnotationAwareOrderComparator 排序后執行。
避坑提醒:
- 內部方法調用不會觸發 @Transactional(繞過代理)
- @Transactional 默認僅回滾運行時異常
- 事件監聽器順序未設置可能導致邏輯混亂
- 事務+事件混用時注意異步監聽器提前執行(事務未提交)
總結
本文深入解析Spring框架的事務管理和事件機制兩大核心功能。在事務管理方面,詳細介紹了@Transactional注解的使用、7種事務傳播行為、異常回滾策略及底層實現原理;在事件機制方面,講解了自定義事件定義、發布訂閱模式實現、異步監聽及優先級控制。文章特別強調了實際開發中的常見陷阱,如內部方法調用失效、異常回滾范圍、事件監聽順序等問題,幫助開發者避免潛在錯誤。通過掌握這些關鍵知識點,能夠有效提升企業級應用的可靠性、可維護性和擴展性。