天天看點

Spring 5 中文解析資料存儲篇-了解Spring事物抽象

Spring核心篇章: Spring 5 中文解析之核心篇-IoC容器 Spring 5 中文解析核心篇-IoC容器之依賴關系 Spring 5 中文解析核心篇-IoC容器之Bean作用域 Spring 5 中文解析核心篇-IoC容器之自定義Bean性質 Spring 5 中文解析核心篇-IoC容器之BeanDefinition繼承與容器拓展點 Spring 5 中文解析核心篇-IoC容器之基于注解的容器配置 Spring 5 中文解析核心篇-IoC容器之類路徑掃描群組件管理 Spring 5 中文解析核心篇-IoC容器之JSR330标準注解 Spring 5 中文解析核心篇-IoC容器之基于Java容器配置 Spring 5 中文解析核心篇-IoC容器之Environment抽象 Spring 5 中文解析核心篇-IoC容器之ApplicationContext與BeanFactory Spring 5 中文解析核心篇-IoC容器之Resources Spring 5 中文解析核心篇-IoC容器之資料校驗、資料綁定和類型轉換 Spring 5 中文解析核心篇-IoC容器之SpEL表達式 Spring 5 中文解析核心篇-IoC容器之AOP程式設計(上) ") Spring 5 中文解析核心篇-IoC容器之AOP程式設計(下) Spring 5 中文解析核心篇-IoC容器之Spring AOP API Spring測試篇章: Spring 5 中文解析測試篇-Spring測試 Spring 5 中文解析核心篇-內建測試之概要和內建測試注解 Spring 5 中文解析核心篇-內建測試之TestContext(上) Spring 5 中文解析核心篇-內建測試之TestContext(中) Spring 5 中文解析測試篇-內建測試之TestContext(下) Spring 5 中文解析測試篇-Spring MVC測試架構 Spring 5 中文解析測試篇-WebTestClient Spring存儲篇章: Spring 5 中文解析資料存儲篇-Spring架構的事物支援模型的優勢 完整 電子書位址

1.2 了解Spring架構事物抽象

Spring事務抽象的關鍵是事務政策的概念。事務政策由

TransactionManager

定義,特别是用于指令式事務管理的

org.springframework.transaction.PlatformTransactionManager

接口和用于響應式事務管理的

org.springframework.transaction.ReactiveTransactionManager

接口。以下清單顯示了

PlatformTransactionManager

API的定義:

public interface PlatformTransactionManager extends TransactionManager {

    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;

    void commit(TransactionStatus status) throws TransactionException;

    void rollback(TransactionStatus status) throws TransactionException;
}           

盡管你可以從應用程式代碼中以

程式設計方式

使用它,但它主要是一個服務提供接口(SPI)。由于

PlatformTransactionManager

是接口,是以可以根據需要輕松對其進行模拟或存根。它與

JNDI

之類的查找政策無關。與Spring架構IoC容器中的任何其他對象(或bean)一樣,定義了

PlatformTransactionManager

實作。這一優點使Spring架構事務成為值得抽象的,即使在使用

JTA

時也是如此。與直接使用

JTA

相比,你可以更輕松地測試事務代碼。

同樣,為了與Spring的理念保持一緻,可以由任何

PlatformTransactionManager

接口方法抛出的

TransactionException

未檢查異常(也就是說,它擴充了

java.lang.RuntimeException

類)。事物基礎架構故障幾乎總是緻命的。在極少數情況下,應用程式代碼實際上可以從事務失敗中恢複,應用程式開發人員仍然可以選擇捕獲和處理

TransactionException

。實際一點是,開發人員沒有被迫這樣做。

getTransaction(..)

方法根據

TransactionDefinition

參數傳回

TransactionStatus

對象。如果目前調用堆棧中存在比對的事務,則傳回的

TransactionStatus

可能表示一個新事務或一個現有事務。後一種情況的含義是,與Java EE事務上下文一樣,

TransactionStatus

與執行線程相關聯。

從Spring架構5.2開始,Spring還為使用響應式類型或

Kotlin

協程的響應式應用程式提供了事務管理抽象。以下清單顯示了由

org.springframework.transaction.ReactiveTransactionManager

定義的事務政策:

public interface ReactiveTransactionManager extends TransactionManager {

    Mono<ReactiveTransaction> getReactiveTransaction(TransactionDefinition definition) throws TransactionException;

    Mono<Void> commit(ReactiveTransaction status) throws TransactionException;

    Mono<Void> rollback(ReactiveTransaction status) throws TransactionException;
}           

響應式事務管理器主要是服務提供接口(SPI),盡管你可以從應用程式代碼中以

使用它。由于

ReactiveTransactionManager

是接口,是以可以根據需要輕松對其進行模拟或存根。

TransactionDefinition

接口指定:

  • 傳播:通常,事務範圍内的所有代碼都在該事務中運作。但是,如果在已存在事務上下文的情況下運作事務方法,則可以指定行為。例如,代碼可以在現有事務中繼續運作(常見情況),或者可以暫停現有事務并建立新事務。Spring提供了

    EJB

    CMT

    熟悉的所有事務傳播選項。要了解有關Spring中事務傳播的語義的資訊,請參閱 事務傳播
  • 隔離:此事務與其他事務的工作隔離的程度。例如,此事務能否看到其他事務未送出的寫入?
  • 逾時:該事務在逾時之前将運作多長時間,并由基礎事務基礎結構自動復原。
  • 隻讀狀态:當代碼讀取但不修改資料時,可以使用隻讀事務。在某些情況下,例如使用

    Hibernate

    時,隻讀事務可能是有用的優化。

這些設定反映了标準的事物概念。如有必要,請參考讨論事務隔離級别和其他核心事務概念的資源。了解這些概念對于使用Spring架構或任何事務管了解決方案至關重要。

TransactionStatus

接口為事務代碼提供了一種控制事務執行和查詢事務狀态的簡單方法。這些概念應該很熟悉,因為它們對于所有事務API都是通用的。以下清單顯示了

TransactionStatus

接口:

public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {

    @Override
    boolean isNewTransaction();

    boolean hasSavepoint();

    @Override
    void setRollbackOnly();

    @Override
    boolean isRollbackOnly();

    void flush();

    @Override
    boolean isCompleted();
}           

無論你在Spring中選擇聲明式還是程式設計式事務管理,定義正确的

TransactionManager

實作都是絕對必要的。通常,你可以通過依賴注入來定義此實作。

TransactionManager

實作通常需要了解其工作環境:

JDBC

JTA

Hibernate

等。

TransactionManager

JDBC

JTA

Hibernate

等。以下示例顯示了如何定義本地

PlatformTransactionManager

實作(在這種情況下,使用純

JDBC

)。

你可以通過建立類似于以下内容的bean來定義

JDBC

資料源:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
</bean>           

然後,相關的

PlatformTransactionManager

Bean定義将引用

DataSource

定義。它應類似于以下示例:

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>           

如果你在Java EE容器中使用

JTA

,則可以使用通過

JNDI

獲得的容器

DataSource

以及Spring的

JtaTransactionManager

。以下示例顯示了

JTA

JNDI

查找:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/jee
        https://www.springframework.org/schema/jee/spring-jee.xsd">

    <jee:jndi-lookup id="dataSource" jndi-name="jdbc/jpetstore"/>

    <bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager" />

    <!-- other <bean/> definitions here -->

</beans>           

JtaTransactionManager

不需要了解資料源(或任何其他特定資源),因為它使用了容器的全局事務管理基礎結構。

dataSource

bean的先前定義使用jee名稱空間中的标記。有關更多資訊,參考 JEE Schema

你還可以輕松使用

Hibernate

本地事務,如以下示例所示。在這種情況下,你需要定義一個

Hibernate

LocalSessionFactoryBean

,你的應用程式代碼可使用該

Hibernate

LocalSessionFactoryBean

擷取

Hibernate

Session

執行個體。

DataSource

bean定義與先前顯示的本地

JDBC

示例相似,是以在以下示例中未顯示。

如果通過

JNDI

查找資料源(由任何非

JTA

事務管理器使用)并由Java EE容器管理,則該資料源應該是非事務性的,因為Spring架構(而不是Java EE容器)管理事務。

在這種情況下,

txManager

bean是

HibernateTransactionManager

類型。就像

DataSourceTransactionManager

需要引用資料源一樣,

HibernateTransactionManager

需要引用

SessionFactory

。以下示例聲明了

sessionFactory

txManager

bean:

<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="mappingResources">
        <list>
            <value>org/springframework/samples/petclinic/hibernate/petclinic.hbm.xml</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <value>
            hibernate.dialect=${hibernate.dialect}
        </value>
    </property>
</bean>

<bean id="txManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>           

如果使用

Hibernate

和Java EE容器管理的

JTA

事務,則應使用與前面的

JDBC

JTA

示例相同的

JtaTransactionManager

,如以下示例所示:

<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>           

JTA

,則無論使用哪種資料通路技術(無論是

JDBC

Hibernate

JPA

或任何其他受支援的技術),事務管理器定義都應該相同。這是由于

JTA

事務是全局事務,它可以征用任何事務資源。

在所有這些情況下,無需更改應用程式代碼。你可以僅通過更改配置來更改事務的管理方式,即使更改意味着從本地事務轉移到全局事務,反之亦然。

作者

個人從事金融行業,就職過易極付、思建科技、某網約車平台等重慶一流技術團隊,目前就職于某銀行負責統一支付系統建設。自身對金融行業有強烈的愛好。同時也實踐大資料、資料存儲、自動化內建和部署、分布式微服務、響應式程式設計、人工智能等領域。同時也熱衷于技術分享創立公衆号和部落格站點對知識體系進行分享。關注公衆号:青年IT男 擷取最新技術文章推送!

部落格位址:

http://youngitman.tech

CSDN:

https://blog.csdn.net/liyong1028826685

微信公衆号:

Spring 5 中文解析資料存儲篇-了解Spring事物抽象

技術交流群:

Spring 5 中文解析資料存儲篇-了解Spring事物抽象