Spring Boot事務管理和@Transactional注解(上)
摘要 本文主要介紹基于Spring Boot的事務管理,尤其是@Transactional注解詳細用法。首先,簡要介紹Spring Boot中如何開啟事務管理;其次,介紹在Spring,Spring Boot和Mybatis框架中的事務管理方式;然后,介紹了事務的五個屬性,包括事務傳播行為和事務隔離級別等;最后,介紹了注解@Transactional屬性。
1 事務概念
- 原子性(Atomicity):事務是一個原子操作,由一系列動作組成。事務的原子性確保動作要么全部完成,要么完全不執行。
- 一致性(Consistency):一旦事務完成(不管成功還是失敗),系統必須確保它所建模的業務處于一致的狀態,而不會是部分完成部分失敗。在現實中的數據不應該被破壞。
- 隔離性(Isolation):可能有許多事務會同時處理相同的數據,因此每個事務都應該與其它事務隔離開來,防止數據損壞。
- 持久性(Durability):一旦事務完成,無論發生什么系統錯誤,它的結果都不應該受到影響,這樣就能從任何系統崩潰中恢復過來。通常情況下,事務的結果被寫到持久化存儲器中。
2 Spring Boot開啟事務管理
本節直接研究Spring Boot中事務的開啟方法。
Spring Boot內部提供的事務管理器是根據@AutoConfigure來進行決定的,當我們使用spring-boot-starter-jdbc或spring-boot-starter-data-jpa依賴的時候,框架會自動分別注入DataSourceTransactionManager或JpaTransactionManager。這兩個事務管理器都實現了Spring中提供的PlatformTransactionManager接口,它是Spring的事務核心接口。
Spring Boot 默認集成事務,所以無須手動開啟。使用注解 @EnableTransactionManagement后,Spring 會自動掃描添加@Transactional注解的方法和類。在Spring Boot中推薦使用@Transactional注解來申明事務。
<beans:bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="entityManagerFactory" ref="entityManagerFactory" />
</beans:bean>
<!-- 聲明使用注解式事務 -->
<tx:annotation-driven transaction-manager="transactionManager" />
dataSource是在Spring配置文件中定義的數據源的對象實例,EntityManagerFactory是基于JPA使用的實體類管理器:org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean。這些都是用來配置與數據庫的連接信息,本質上,@Transactional使用了JDBC的事務來進行事務控制的。
<annotation-driven>標簽的聲明,則是在Spring內部啟用@Transactional來進行事務管理,類似開關之類的聲明。
3 核心接口
Spring事務管理的實現有許多細節,如果對整個接口框架有個大體了解會非常有利于我們理解事務,下面通過講解Spring的事務接口來了解Spring實現事務的具體策略。Spring事務管理涉及的接口的聯系如下:

Spring并不直接管理事務,而是提供了多種事務管理器,管理器將事務管理的職責委托給Hibernate或者JTA等持久化機制所提供的相關平臺框架的事務來實現,它的接口是org.Springframework.transaction.PlatformTransactionManager,通過這個接口,Spring為各個平臺如JDBC、Hibernate等都提供了對應的事務管理器,但是具體的實現就是各個平臺自己的事情了。此接口的內容如下:
|
public interface PlatformTransactionManager { TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; void commit(TransactionStatus status) throws TransactionException; void rollback(TransactionStatus status) throws TransactionException; } |
TransactionStatus接口表示事務的狀態,比如事務是否是一個剛構造的事務,事務是否已經執行完成等狀態。
4 事務管理方式
Spring支持編程式事務管理和聲明式事務管理兩種方式。編程式事務管理使用TransactionTemplate或者直接使用底層的PlatformTransactionManager,Spring推薦使用TransactionTemplate。
聲明式事務管理在底層是建立在AOP之上的。其本質是在方法前后進行攔截,然后在目標方法開始之前創建或者加入一個事務,在執行完目標方法之后根據執行情況提交或者回滾事務。聲明式事務最大的優點就是不需要通過編程的方式管理事務,這樣就不需要在業務邏輯代碼中摻雜事務管理的代碼,只需在配置文件中做相關的事務規則聲明(或通過基于@Transactional注解的方式),便可以將事務規則應用到業務邏輯中。
顯然聲明式事務管理要優于編程式事務管理,這正是Spring倡導的非侵入式的開發方式。聲明式事務管理使業務代碼不受污染,一個普通的POJO對象只要加上注解就可以獲得完全的事務支持。和編程式事務相比,聲明式事務唯一的不足之處是,后者的最細粒度只能作用到方法級別,無法做到像編程式事務那樣可以作用到代碼塊級別。但是即便有這樣的需求,也存在很多變通的方法,比如,可以將需要進行事務管理的代碼塊獨立為方法等等。
聲明式事務管理也有兩種常用的方式,一種是使用<tx:advice>進行聲明式事務管理,另一種就是基于Java注解@Transactional。顯然后者更簡單易用,更清爽。
MyBatis自動參與到Spring事務管理中,無需額外配置,只要org.mybatis.Spring.SqlSessionFactoryBean引用的數據源與DataSourceTransactionManager或JpaTransactionManager引用的數據源一致即可;否則,事務管理會不起作用。
預知后事如何,請聽下回分解——Spring Boot事務管理(中)
Buy me a coffee. ?Get red packets.
浙公網安備 33010602011771號