spring入門(三)【事務控制】,spring入門事務控制

來源:互聯網
上載者:User

spring入門(三)【事務控制】,spring入門事務控制

在開發中需要操作資料庫,進行增、刪、改操作的過程中屬於一次操作,如果在一個業務中需要更新多張表,那麼任意一張表的更新失敗,整個業務的更新就是失敗,這時那些更新成功的表必須復原,否則業務會出錯,這時就要用到事務,即這個業務的操作屬於一個事務,事務具有原子性、隔離性、一致性、持久性。這時便用到了事務,事務控制的目的是保證一組操作要麼全部成功,要麼全部失敗。spring提供了對事務的支援,在spring中主要有兩種方式使用事務,一、編程式事務控制;二、聲明式事務控制。

一、編程式事務控制

所謂編程式事務控制即通過編寫代碼的方式實現事務的控制。

spring為了方便處理事務,提供了交易管理員,對事務的控制歸根到底是通過交易管理員進行控制,在spring中所有的事務控制必須要有交易管理員。下面是一個編程式事務控制的例子,實現賬戶之間的轉賬,我們把對事務的控制放在系統的service層(分為controller層、service層、DAO層)來處理,下面是我的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:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"><!--spring 自動檢測--><context:component-scan base-package="com.cn.study.day5" /><!----><context:property-placeholder location="classpath:db.properties"/><!---->     <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName"><value>${db.driver}</value></property><property name="url"><value>${db.url}</value></property><property name="username"><value>${db.username}</value></property><property name="password"><value>123456</value></property></bean><bean id="dao" class="com.cn.study.day5.service.inter.impl.AccountDaoImpl"><property name="dataSource" ref="dataSource"></property></bean><!--配置交易管理員--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><!--交易管理員模板 方便使用事務--><bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"><property name="transactionManager" ref="transactionManager"></property></bean></beans>

  配置了交易管理員,這裡使用DataSourceTransactionManager,交易管理員有一個dataSource屬性必須配置,這裡使用ref屬性引用上邊的。有了交易管理員之後要使用事務還是比較麻煩,spring又提供了交易管理員模板,我們配置交易管理員模板,交易管理員模板需要一個交易管理員屬性,我們引用上邊的交易管理員。至此關於編程式的事務控制的設定檔已經準備完畢,下面進行編程式開發。由於,我們把事務控制放在service層,下面是我的service層的代碼,

package com.cn.study.day5.service.inter.impl;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.support.TransactionCallback;import org.springframework.transaction.support.TransactionCallbackWithoutResult;import org.springframework.transaction.support.TransactionTemplate;import com.cn.study.day5.service.inter.AccountDaoInter;import com.cn.study.day5.service.inter.AccountServiceIter;@Componentpublic class AccountServiceImpl implements AccountServiceIter {    @Autowired    private AccountDaoInter adi;    @Autowired    private TransactionTemplate tt;    //轉賬方法,由out向in轉money元    @Override    public void transfer(final String out, final String in, final double money) {        // TODO Auto-generated method stub        //使用交易管理員模板進行事務控制        tt.execute(new TransactionCallbackWithoutResult() {            @Override            protected void doInTransactionWithoutResult(TransactionStatus status) {                // TODO Auto-generated method stub                adi.outMoney(out, money);                //一個異常,使用了事務控制,在出現了異常之後,事務會復原                int i = 1 / 0;                adi.inMoney(in, money);            }        });    }}

由於是面向介面編程,這裡我只貼出了service層的實現,使用了自動掃描機制(掃描類、屬性上的註解@Component、@Autowired),transfer方法是實現轉賬的方法,首先從一個賬戶轉出,然後轉入另一個賬戶,使用交易管理員模板的execute方法,需要一個TransactionCallBack的執行個體,這裡使用匿名內部類的方式,把要執行的方法放在doInTransactionWithoutResult中執行,保證了事務的控制。

使用這種方式可以保證事務控制,但是在實際開發過程當中這種方式對代碼的改動太大,不符合低侵入開發原則,所有這種方式在開發中幾乎很少用到,用的最多的是聲明式的事務控制。

 

二、聲明式事務控制

聲明式事務控制又分為三種方式,一、基於TransactionProxyFactoryBean代理的聲明式事務控制;二、使用AOP的聲明式事務控制;三、基於@Transactional註解的聲明式事務控制。

1、基於TransactionProxyFactoryBean的聲明式事務控制

TransactionProxyFactoryBean是事務的代理類,spring會為目標類產生一個代理,具體的配置如下,

<!--配置交易管理員-->    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">        <property name="dataSource" ref="dataSource"></property>    </bean>    <!--配置業務層代理-->    <bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">        <property name="target" ref="accountServiceImpl"></property>        <property name="transactionManager" ref="transactionManager"></property>        <property name="transactionAttributes">            <props>                <prop key="transfer"></prop>            </props>        </property>    </bean>

這裡只貼出了交易管理員和業務層代理的配置,剩餘的資料來源和業務類的配置可以執行配置,前面說到無論使用哪種方式配置交易管理,都需要使用交易管理員。重點看業務層代理,配置的class屬性為TransactionProxyFactoryBean,需要配置三個屬性:target(要代理的具體業務層實作類別)、transactionManager(交易管理員)、transactionAttributes(要攔截的業務層方法)。配置完成之後,便可以進行測試,測試代碼如下,

ApplicationContext ac=getApplicationContext();        AccountServiceIter asi=(AccountServiceIter)ac.getBean("accountServiceProxy");        asi.transfer("aa", "cc", 10d);

通過getApplicationContext()方法獲得了ApplicationContext執行個體,然後獲得accountServiceProxy的執行個體,這裡獲得的不是AccountServiceImpl的執行個體而是代理的執行個體對象,因為使用代理,代理了實際的業務類,所有這裡不能再使用實際的類而應是代理類。

使用這種方式的需要為每一個需要使用事務的業務類配置一個代理比教麻煩,所以在開發過程中這種方式幾乎不用。

2、使用AOP的聲明式事務控制

這種方式是在開發過程中使用的比較多的一種,配置如下,

<!--配置交易管理員-->    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">        <property name="dataSource" ref="dataSource"></property>    </bean>    <!--配置事務增強-->    <tx:advice id="advicer" transaction-manager="transactionManager">        <tx:attributes>            <tx:method name="transfer*" propagation="REQUIRED"/>        </tx:attributes>    </tx:advice>    <!--配置切點、事務通知-->    <aop:config>        <aop:pointcut id="myPointcut" expression="execution(* com.cn.study.day555.service.inter.impl.*.*(..))"/>        <aop:advisor advice-ref="advicer" pointcut-ref="myPointcut"/>    </aop:config>

配置了事務增強<tx:advice>配置對要增強方法的事務的傳播行為等,配置<aop:config>配置切點和對應的事務通知,這樣就完成了AOP的聲明式事務控制。

3、基於@Transactional註解

使用@Transactional註解需要再設定檔中開啟對這個註解的掃描:<tx:annotation-driven transaction-manager="transactionManager" />,引用了交易管理員,然後就可以使用@Transactional註解,此註解可以使用在類上,也可以使用在方法上,使用在類上即對此類的所有方法都起作用,使用在方法上則表示對單個方法起作用,還可以配置一些屬性,放在另一篇文章中進行解釋。

通過對以上四種配置事務的方式的描述,其中聲明式方式中的第二種方式使用比較普通,對代碼的侵入比較小,第三種因為配置簡單,也比較常用,但是需要在業務類或方法上加@Transcational註解,對代碼有一定的侵入。

有不正之處歡迎指出,謝謝!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.