天天看點

Spring 使用xml配置事務

第一步,建立 xml 檔案,并聲明xml 命空間:

<?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:aop="http://www.springframework.org/schema/aop"
       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/aop
       http://www.springframework.org/schema/aop/spring-aop.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
">
<!-- 在這裡添加配置 -->
</beans>
           

第二步,配置 spring 事務管理器的 bean。

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

第三步,我們已經有了事務管理器,接下來配置它的生效規則。

<tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="get*" read-only="true" propagation="SUPPORTS"/>
            <tx:method name="*"/>
        </tx:attributes>
</tx:advice>
           

對上面的配置作下說明:

id: 唯一辨別。雖然配置了事務管理器對方法進行攔截的規則,但是還沒有和切入點聯系起來,比如要攔截哪個包下方法?哪個類下的方法?擁有哪些參數清單的方法?這些都要等着第四步的切入點配置完成後才能确定。

transaction-manager: 事務管理器。毋庸置疑,是我們第二步中配置的事務管理bean。

tx:method 中的 name: 對哪些方法進行攔截。

  • get* 表示所有名稱以 get 開頭的方法。對于這些方法,不用開啟事務,并且是隻讀操作,不會修改資料。
    • 表示所有方法,propagation 不寫會使用預設值 REQUIRED, 意思是開啟事務。read-only 不寫預設值是 false,表示會對資料進行寫操作。

上面兩個通配符,比對範圍小的優先級高。所有, 當比對到 get* 時,優先使用 get* 的配置,也就是不開啟事務。

第四步,配置 aop。事務管理器也是通過 aop 原理來工作的,這和其它的切面類并沒有差別。既然其它的切面類是通過 aop來配置,它也不能例外。

<aop:config>
        <aop:pointcut id="pt1" expression="execution(* com.zfy.service.impl.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/>
</aop:config>
           

aop:pointcut

定義了切入點。切入點是以方法為最小機關的。其中的 expression 就定義了這個切點包含的方法。可以看到使用了通配符比對了 com.zfy.service.impl 包下的所有方法。

aop:advisor 通過兩個 ref 屬性将事務管理器的相應規則應用到定義好的切點上。

這樣,Spring 事務管理就配置成功了。至于其它的 bean 配置,比如 JdbcTemplate, DataSource,可以參考下面的完整配置:

<?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:aop="http://www.springframework.org/schema/aop"
       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/aop
       http://www.springframework.org/schema/aop/spring-aop.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
">

    <bean id="accountService" class="com.zfy.service.impl.AccountServiceImpl">
        <property name="dao" ref="accountDao"/>
    </bean>
    <bean id="accountDao" class="com.zfy.dao.impl.AccountDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>

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

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/ioc"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>

    <!--    配置事務管理bean-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--    配置事務通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="find*" read-only="true" propagation="SUPPORTS"/>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>

    <!--    配置 aop-->
    <aop:config>
        <aop:pointcut id="pt1" expression="execution(* com.zfy.service.impl.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/>
    </aop:config>
</beans>