Spring宣告式事務純xml模式回顧

ruoshui__999發表於2020-12-28

Spring宣告式事務純xml模式回顧

  • Spring中事務的API

mybatis: sqlSession.commit();
hibernate: session.commit();

PlatformTransactionManager

public interface PlatformTransactionManager {
/**
 * 獲取事務狀態資訊
 */
 TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;
 /**
 * 提交事務
 */
 void commit(TransactionStatus status) throws TransactionException;
 /**
 * 回滾事務
 */
 void rollback(TransactionStatus status) throws TransactionException;
}

作⽤
此接⼝是Spring的事務管理器核⼼接⼝。Spring本身並不⽀持事務實現,只是負責提供標準,應⽤底層
⽀持什麼樣的事務,需要提供具體實現類。此處也是策略模式的具體應⽤。在Spring框架中,也為我們
內建了⼀些具體策略,例如:DataSourceTransactionManager , HibernateTransactionManager 等
等。( 和 HibernateTransactionManager 事務管理器在 spring-orm-5.1.12.RELEASE.jar 中)
Spring JdbcTemplate(資料庫操作⼯具)、Mybatis(mybatis-spring.jar)————>
DataSourceTransactionManager
Hibernate框架 ——————> HibernateTransactionManager
DataSourceTransactionManager 歸根結底是橫切邏輯程式碼,宣告式事務要做的就是使⽤Aop(動態代
理)來將事務控制邏輯織⼊到業務程式碼

  • Spring 宣告式事務配置

    導⼊jar

<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-context</artifactId>
 <version>5.1.12.RELEASE</version>
</dependency>
<dependency>
 <groupId>org.aspectj</groupId>
 <artifactId>aspectjweaver</artifactId>
 <version>1.9.4</version>
</dependency>

<!--引入spring宣告式事務相關 但凡是資料庫操作,這兩個都需要被引入-->
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-jdbc</artifactId>
 <version>5.1.12.RELEASE</version>
</dependency>
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-tx</artifactId>
 <version>5.1.12.RELEASE</version>
</dependency>

xml 配置

<!--<beans></beans>中引入事物的依賴 專門針對事務的標籤-->
xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd


    <!--spring宣告式事務配置,宣告式事務無非就是配置一個aop,只不過有些標籤不一樣罷了-->
    <!--橫切邏輯-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--控制事務歸根結底底層還是通過控制連線,所以要依賴資料來源-->
        <constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
    </bean>

    <!--增強-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!--定製事務細節,傳播行為,隔離級別等-->
        <!--
            read-only是否只讀
            propagation="REQUIRED"傳播行為:要求有事務
            isolation="DEFAULT"隔離級別:預設,即按照資料庫預設隔離級別,如果不配也是預設的
            timeout="-1" 不限制超時時間
        -->
        <tx:attributes>
            <!--一般性配置-->
            <tx:method name="*" read-only="false" propagation="REQUIRED" isolation="DEFAULT" timeout="-1"/>
            <!--針對查詢的覆蓋性配置-->
            <tx:method name="query*" read-only="true" propagation="SUPPORTS"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <!--advice-ref指向增強=橫切邏輯+方位-->
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.lagou.edu.service.impl.TransferServiceImpl.*(..))"/>
    </aop:config>

新增了事務,業務方法執行要麼全部成功,要麼全部不成功。
如下程式碼有異常,因為新增了事務,所以這兩條語句的執⾏都不會成功。

accountDao.updateAccountByCardNo(to);
int c = 1/0;
accountDao.updateAccountByCardNo(from);
  • 完整的xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans  xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        https://www.springframework.org/schema/tx/spring-tx.xsd
">

    <!--開啟註解掃描,base-package指定掃描的包路徑-->
    <context:component-scan base-package="com.lagou.edu"/>

    <!--引入外部資原始檔-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--第三方jar中的bean定義在xml中-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
     </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <constructor-arg name="dataSource" ref="dataSource"/>
    </bean>


    <!--spring宣告式事務配置,宣告式事務無非就是配置一個aop,只不過有些標籤不一樣罷了-->
    <!--橫切邏輯-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--控制事務歸根結底底層還是通過控制連線,所以要依賴資料來源-->
        <constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
    </bean>

    <!--增強-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!--定製事務細節,傳播行為,隔離級別等-->
        <!--
            read-only是否只讀
            propagation="REQUIRED"傳播行為:要求有事務
            isolation="DEFAULT"隔離級別:預設,即按照資料庫預設隔離級別,如果不配也是預設的
            timeout="-1" 不限制超時時間
        -->
        <tx:attributes>
            <!--一般性配置-->
            <tx:method name="*" read-only="false" propagation="REQUIRED" isolation="DEFAULT" timeout="-1"/>
            <!--針對查詢的覆蓋性配置-->
            <tx:method name="query*" read-only="true" propagation="SUPPORTS"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <!--advice-ref指向增強=橫切邏輯+方位-->
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.lagou.edu.service.impl.TransferServiceImpl.*(..))"/>
    </aop:config>
</beans>

相關文章