關於spring中事務管理的幾件小事

1.Spring中的事務管理

  • 做爲企業級應用程序框架,Spring在不一樣的事務管理API之上定義了一個抽象層。而應用程序開發人員沒必要了解底層的事務管理API,就可使用Spring的事務管理機制。
  • Spring既支持編程式事務管理,也支持聲明式的事務管理。
  • 編程事務管理:將事務管理代碼嵌入到業務方法中來控制事務的提交和回滾。在編程式管理事務時,必須在每一個事務操做中包含額外的事務管理代碼。
  • 聲明式事務管理:大多數狀況下比編程式事務管理更好用。它將事務管理代碼從業務方法中分離出來,以聲明的方式來實現事務管理。事務管理做爲一種橫切關注點,能夠經過AOP方法模塊化。Spring經過SpringAOP框架支持聲明式事務管理。

2.Spring中的事務管理器

  • Spring從不一樣的事務管理API中抽象了一整套的事務機制。開發人員沒必要了解底層的事務API,就能夠利用這些事務機制。有了這些事務機制,事務管理代碼就能獨立於特定的事務技術了。
  • Spring的核心事務管理抽象是TransactionManager管理封裝了一組獨立於技術的方法。不管使用Spring的那種事務管理策略(編程式或聲明式),事務管理器都是必須的。
  • DataSourceTransactionManager:在應用程序中只須要處理一個數據源,並且經過JDBC存儲。
  • JtaTransactionManager:在JavaEES應用服務器上用JTA進行事務管理。
  • HibernateTransactionManager:用Hibernate框架存取數據庫。
  • 事務管理器以普通的Bean形式聲明在SpringIOC容器中。java

    3.用事務通知聲明式地管理事務

  • 事務管理是一種橫切關注點。
  • 爲了在Spring 2.x中啓用聲明式事務管理,能夠經過tx Schema中定義的 元素聲明事務通知。爲此必須事先將這個Schema定義添加到 根元素中去。
  • 聲明瞭事務通知後,就須要將它與切入點關聯起來,因爲事務通知是在 元素外部聲明的,索引它沒法直接與切入點產生關聯,因此必須在 元素中聲明一個加強器通知與切入點關聯起來。
  • 因爲Spring AOP是基於代理的方法,索引只能加強公共方法。所以,只有公有方法才能經過Spring AOP進行事務管理。
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
         <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <tx:advice id="bookShopTxAdvice" transaction-manager="transactionManager"></tx:advice>
    
    <aop:config>
        <aop:pointcut id="bookShopOperation" expression="execution(* *.BookShopService.*(..))"></aop:pointcut>
        <aop:advisor advice-ref="bookShopTxAdvice" pointcut-ref="bookShopOperation"/>
    </aop:config>

4.用@Transactional註解聲明式的管理事務

  • 除了在帶有切入點,通知和加強器的Bean配置文件中聲明事務外,Spring還容許簡單地用@Transactional註解來標註事務方法,。
  • 爲了將方法定義爲支持事務處理的,能夠爲方法添加@Transactional註解。根據Spring AOP基於代理機制,只能標註公有方法。
  • 能夠在方法或者類級別上添加@Transactional註解。當把這個註解應用到類上時,這個類中的全部公共方法都會被定義成支持事務處理的。
  • 在Bean配置文件中只須要啓用 元素,併爲之指定事務處理器就能夠了。
  • 若是事務處理器的名稱是transactionManager,就能夠在 元素中省略transaction-manager屬性。這個元素會自動檢測該名稱的事務處理器。
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <context:component-scan base-package="com.desparado.service"></context:component-scan>
    
    <tx:annotation-driven/>

5.事務傳播屬性

  • 當事務方法被另外一個事務方法調用時,必須指定事務應該如何傳播,例如:方法可能繼續在現有事務中運行,也可能開啓一個新事務,並在本身的事務中運行。
  • 事務的傳播行爲能夠由傳輸屬性指定,Spring定義了7種傳播行爲。
傳播屬性 描述
REQUIRED 若是有事務在運行,當前的方法就在這個事務內部運行,不然,就啓動一個新的事務,並在本身的事務內運行。
REQUIRED_NEW 當前的方法必須啓動新事務,並在它本身的事務內運行,若是有事務正在運行,應該將它掛起
SUPPORTS 若是有事務在運行,當前的方法就在這個事務內運行,不然它能夠不容許在事務中
NOT_SUPPORTED 當前的方法不該該運行在事務中,若是有運行的事務,將它掛起
MANDATORY 當期的方法必須運行在事務內部,若是沒沒有正在運行的事務,就拋出異常
NEVER 當前的方法不該該運行在事務中,若是有運行的事務,就跑出異常
NESTED 若是有事務在運行,當前的方法就應該在這個事務的嵌套事務內運行,不然,就啓動一個新的事務,並在它本身的事務內運行
  • 事務傳播屬性的配置
    在@Transactional註解中的屬性中進行配置
@Transactional(propagation=Propagation.REQUIRES_NEW)

在xml中能夠在 中進行配置 spring

<tx:advice id="bookShopTxAdvice" transaction-manager="transactionManager">
    <tx:attributes>
          <tx:method name="purchase" propagation="REQUIRES_NEW"/>
    </tx:attributes>
</tx:advice>

6.設置隔離事務屬性

  • 用@Transactional註解聲明式地管理事務時能夠在@Transactional的isolation屬性中設置隔離級別
@Transactional(propagation=Propagation.REQUIRES_NEW,isolation=Isolation.READ_COMMITTED)
  • 在Spring 2.x事務通知中,能夠在<tx:method》元素中指定隔離級別
<tx:advice id="bookShopTxAdvice" transaction-manager="transactionManager">
    <tx:attributes>
          <tx:method name="purchase" propagation="REQUIRES_NEW" 
              isolation="READ_COMMITTED"/>
    </tx:attributes>
</tx:advice>

7.設置回滾事務屬性

  • 默認狀況下只有未檢查異常(RuntimeException和Error類型的異常)會致使事務回滾,二受檢查異常不會。
  • 事務的回滾規則能夠經過@Transactional註解的rollbackFor和noRollbackFor屬性來定義,這兩個屬性被聲明爲Class[]類型的,所以能夠爲這兩個屬性指定多個異常類。
    - rollbackFor:遇到時必須進行回滾。
    - noRollbackFor:一組異常類,遇到時必須不會滾sql

    @Transactional(propagation=Propagation.REQUIRED_NEW,
                  isolation=Isolation.READ_COMMITTED,
                  rollbackFor=(IOException.class,SQLException.class),
                  noRollbackFor=ArithmeticException.class)  
    public void purchase(String isbn,String username){}
  • 在Spring 2.x事務通知中,能夠在<tx:method》原始種指定回滾規則,若是有不止一種異常,用逗號隔開
<tx:advice id="bookShopTxAdvice" transaction-manager="transactionManager">
   <tx:attributes>
         <tx:method name="purchase" propagation="REQUIRES_NEW" 
             isolation="READ_COMMITTED"
             rollback-for="java.io.IOException,java.sql.SQLException" 
             no-rollback-for="java.lang,ArithmeticException"/>
   </tx:attributes>
</tx:advice>

8.超時和只讀屬性

  • 因爲事務能夠在行和表上得到鎖,所以長事務會佔用資源,並對總體性能產生影響。
  • 若是一個事務只讀取數據但不作修改,數據庫引擎能夠對這個事務進行優化。
  • 超時事務屬性:事務在強制回滾以前能夠保持多久。這樣能夠防止長期運行的事務佔用資源。
  • 只讀事務屬性:表示這個事務只讀取數據庫但不更新數據庫,這樣能夠幫助數據庫引擎優化事務。
  • 超時和只讀屬性能夠在@Transactional註解中定義,超時屬性以秒爲單位。
@Transactional(propagation=Propagation.REQUIRED_NEW,
                isolation=Isolation.READ_COMMITTED,
                rollbackFor=(IOException.class,SQLException.class),
                noRollbackFor=ArithmeticException.class,
                readOnly=true,tomeout=30)  
public void purchase(String isbn,String username){}

-在Spring 2.x事務通知中,超時和只讀屬性能夠在 元素中進行指定 數據庫

<tx:advice id="bookShopTxAdvice" transaction-manager="transactionManager">
    <tx:attributes>
          <tx:method name="purchase" propagation="REQUIRES_NEW" 
              isolation="READ_COMMITTED"
              rollback-for="java.io.IOException,java.sql.SQLException" 
              no-rollback-for="java.lang,ArithmeticException"  
              read-only=true
              timeout=30/>
    </tx:attributes>
</tx:advice>
相關文章
相關標籤/搜索