Spring Boot事務管理(上)


摘要 本文主要介紹基於Spring Boot的事務管理,尤其是@Transactional注解詳細用法。首先,簡要介紹Spring Boot中如何開啟事務管理;其次,介紹在Spring,Spring Boot和Mybatis框架中的事務管理方式;然后,介紹了事務的五個屬性,包括事務傳播行為和事務隔離級別等;最后,介紹了注解@Transactional屬性。 

1 初步理解 

       理解事務之前,先講一個你日常生活中最常干的事:取錢。  
       比如你去ATM機取1000塊錢,大體有兩個步驟:首先輸入密碼金額,銀行卡扣掉1000元錢;然后ATM出1000元錢。這兩個步驟必須是要么都執行要么都不執行。如果銀行卡扣除了1000塊但是ATM出錢失敗的話,你將會損失1000元;如果銀行卡扣錢失敗但是ATM卻出了1000塊,那么銀行將損失1000元。所以,如果一個步驟成功另一個步驟失敗對雙方都不是好事,如果不管哪一個步驟失敗了以后,整個取錢過程都能回滾,也就是完全取消所有操作的話,這對雙方都是極好的。  
       事務就是用來解決類似問題的。事務是一系列的動作,它們綜合在一起才是一個完整的工作單元,這些動作必須全部完成,如果有一個失敗的話,那么事務就會回滾到最開始的狀態,仿佛什么都沒發生過一樣。  
      在企業級應用程序開發中,事務管理是必不可少的技術,用來確保數據的完整性和一致性。  事務有四個特性:ACID 
  • 原子性(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注解來申明事務。

 

     在Spring MVC框架中,為了使用基於@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事務管理(中)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM