Spring學習之聲明式事務管理

Spring學習之聲明式事務管理

前言

在前面的小節(jié)中,我們學習了關于事務的概念以及事務管理的重要性,并且通過編程使用Spring的編程式事務管理進行操作,加深對事務管理的重要性的學習,不過,由于編程式的事務管理使用起來不是很方便,所以在日常的開發(fā)中基本不怎么使用,接下來的內(nèi)容我們將學習使用Spring的聲明式事務管理,這里有一個地方需要明白的是,Spring的聲明式事務管理的實現(xiàn)方式其實是通過AOP的方式來實現(xiàn)的,也就是為原始的事務管理對象創(chuàng)建代理對象,從而實現(xiàn)事務管理增強的

基于TransactionProxyFactoryBean的事務管理配置

經(jīng)過前面的學習,可以知道,Spring中配置AOP有三種方式,分別是通過ProxyFactoryBean創(chuàng)建代理,通過XML的方式以及通過注解的方式,既然Spring事務管理是通過AOP來實現(xiàn)的,那么對應的就有三種不同的方式,首先來看下基于TransactionProxyFactoryBean的管理方式

首先是Spring的配置文件


<?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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!--開啟自動掃描-->
    <context:component-scan base-package="cn.xuhuanfeng.transaction"/>

    <!--配置數(shù)據(jù)源,這里采用dbcp-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="url" value="jdbc:mysql://localhost:3306/spring"/>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="username" value="root"/>
        <property name="password" value="huanfeng"/>
    </bean>

    <!--配置JdbcTemplate-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--注入數(shù)據(jù)源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--配置事務管理-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入數(shù)據(jù)源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--為AccountService創(chuàng)建代理類-->
    <bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <!--注入事務管理-->
        <property name="transactionManager" ref="transactionManager"/>
        <!--注入目標類,也就是所要增強的類-->
        <property name="target" ref="accountService"/>
        <!--配置相應的事務屬性-->
        <property name="transactionAttributes">
            <props>
                <!--指定不同的事務的處理方式
                    配置格式:事務傳播方式,隔離級別,readOnly,-Exception,+Exception
                    傳播行為是唯一必須配置的,其他的如果不配置則使用默認
                    -Exception表示如果發(fā)生對應的異常,則回滾事務
                    +Exception表示即使發(fā)生對應的異常,也依舊提交事務
                -->
                <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop>
            </props>
        </property>
    </bean>
</beans>

對應的持久層代碼


@Repository
public class AccountDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public void transferIn(String name, double money){
        String sql = "update account set money = money + ? where name = ?";

        jdbcTemplate.update(sql, money, name);
    }

    public void transferOut(String name, double money){
        String sql = "update account set money = money - ? where name = ?";

        jdbcTemplate.update(sql, money, name);
    }
}

業(yè)務層代碼

@Service
public class AccountService {

@Autowired
private AccountDao accountDao;

public void transfer(final String fromName,final String toName,final double money){

    accountDao.transferOut(fromName, money);
    int d = 1/0; // 除0異常
    accountDao.transferIn(toName, money);
}

}

通過上面的配置之后,當我們在使用AccountService的時候,由于獲取的對象的代理后的對象,所以Spring會自動進行事務的監(jiān)管,而我們需要做的就是配置對應的事務傳播類型以及事務管理級別等的信息,這種方式明顯對代碼以及沒有什么侵入了,但是使用這種方式意味著沒有都需要為不同的服務對象創(chuàng)建對應的代理對象,這其實是不太方便的,接下來我們來看下使用aop/tx命名空間來進行配置的方式。

基于aop/tx命名空間的事務管理配置

由于是對上面的業(yè)務操作進行事務管理,而且經(jīng)過上一小節(jié)的學習,我們也基本熟悉了該業(yè)務,所以這里直接演示配置的代碼


<?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:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd 
       http://www.springframework.org/schema/aop 
       http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--
        這里配置同前,故省略
    -->

    <!--aop配置-->
    <aop:config>
        <!--配置切點-->
        <aop:pointcut id="serviceMethod" expression="execution(* cn.xuhuanfeng.transaction.AccountService.*(..))"/>
        <!--對應的切面-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
    </aop:config>

    <!--配置事務增強-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!--配置對應的事務管理,其中name為與事務相關的方法名,可以使用通配符-->
            <tx:method name="transfer*" isolation="DEFAULT" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

</beans>

可以看到,通過XML配置的方式,可以更加靈活地進行事務管理

基于注解的事務管理配置

基于注解的配置方式提供了更加簡單的配置方式,只需要使用@Transactional注解進行標注,并且開啟對應的掃描即可。

// 配置相應的隔離級別、事務傳播等
@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED)
@Service
public class AccountService {
    // 省略其他內(nèi)容
}

Spring配置文件也相對比較簡單了


<?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:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--數(shù)據(jù)源配置等同上-->
    <!--通過tx命名空間,開啟主機自動掃描,并且注入事務管理器-->
    <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

可以看到,通過注解配置的方式是最簡單的配置方式,在日常的開發(fā)中,這種方式的使用的頻率也比較高

總結

本小節(jié)主要學習了Spring聲明式事務管理的配置,包括了使用TransactionProxyFactoryBean、通過aop/tx命名空間的XML配置以及基于注解的配置方式,其中,基于注解的配置方式是比較簡單的,也是使用頻率比較高的一種

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,711評論 19 139
  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,290評論 6 342
  • 這部分的參考文檔涉及數(shù)據(jù)訪問和數(shù)據(jù)訪問層和業(yè)務或服務層之間的交互。 Spring的綜合事務管理支持覆蓋很多細節(jié),然...
    竹天亮閱讀 1,111評論 0 0
  • spring官方文檔:http://docs.spring.io/spring/docs/current/spri...
    牛馬風情閱讀 1,861評論 0 3
  • 你是怎么給別人留下深刻印象的? 初次見面的時候是溫文爾雅的舉動嗎?再次見面的時候是細心體貼的做法嗎?熟悉之后是堅持...
    筆尖躍動心儀閱讀 848評論 0 1

友情鏈接更多精彩內(nèi)容