1. 程式人生 > >spring-事物管理

spring-事物管理

1.程式設計式事務

這種需要自己手動編寫事務程式碼的控制方式已經嚴重過時了,因為每個執行DML語句的操作都要編寫一份這樣的程式碼,相當的麻煩,Spring提供了一個抽象層:PlantformTransactionManager,事務管理器。封裝了資料庫事務幾個方法,

commit、rollback、getTransaction。想在Spring平臺使用事務,就必須提供一個

PlantformTransactionManager的子類,Spring有一個實現類:DataSourceTransactionManager。

 

2.Spring事務配置

Spring的事務控制是基於AOP程式設計思想上實現的,配置檔案中需要的Schema:

有tx包的地方也要有aop包。

 

a) 基本配置步驟:

    1.首先宣告一個Datasource,建立事務管理器需要到這個例項。

   <bean id="dataSource"  class="org.springframework.jdbc.datasource.DriverManagerDataSource">
     <property name="url" value="${url}" ></property>  <!-- 添加里面的屬性 -->
     <property name="username" value="${userid}" ></property>
     <property name="password" value="${password2}" ></property>
     <property name="driverClassName" value="${driverClass}" ></property>
   </bean>

    2.宣告一個Spring的事務管理器:

   <!-- 事務管理器  不再使用jdbc的commit和rollback 必須由事務管理器提供 配置事物管理器必須要注入dataSource-->
   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
     <property name="dataSource" ref="dataSource"></property> 
   </bean>

    3.定義通知

<!-- 定義事物裡面的通知  通知的程式碼 spring已經實現  事務管理器如果是transactionManager命名 可以省略 transaction-manager="transactionManager"-->
   <tx:advice id="myAdvise"  transaction-manager="transactionManager">
	   	<tx:attributes>
            <!--tx:method的作用是攔截指定方法開頭的 然後對他進行事物處理 -->
	   	    <tx:method name="update*" propagation="REQUIRED" />
	   	    <tx:method name="save*" />
	   	    <tx:method name="delete*"/>
            <!--read-only="true" 意思是除了上面攔截的以外  其他的都不攔截-->
	   	    <tx:method name="*" read-only="true"/>
	   	</tx:attributes>
   </tx:advice>

 意義:通知的概念知道AOP程式設計的都知道,不多BB ,資料庫事務的前置後置通知的程式碼Spring是 已經封裝好了的,直接指定就OK了。transaction-manager預設值是transactionManager,如果在宣告管理器Bean的時候id為transactionManager,那麼在這裡是 不需要手動指定的,若不是,則手動指定 transaction-manager無論是獲取連線、關閉自動提交、等前置通知,還是異常回滾的異常通知、 業務程式碼 執行完後提交事務的後置通知,Spring都幫我們把相關的邏輯封裝好了, 只需要專注自己的業務邏輯即可。

name

用於指定需要事務支援的方法,update*指的是update開頭的所有方法,以此類推。

 

propagation(傳播級別):

    REQUIRED:如果父方法沒有事務就建立一個事務,如果有就使用當前事務。

    REQUIRED_NEW:無論父方法有沒有事務,都建立一個新的

    SUPPORTS: 如果父方法沒有事務則使用JDBC的事務(自動提交),否則使用父方法的事務

    NOT_SUPPORTS:無論父方法有沒有事務,都是用JDBC的事務(掛起父方法的事務)。

    MANDATORY:如果方法沒有執行在Spring事務中就丟擲異常,必須在事務環境下執行

    NEVER:父方法不能存在事務,有事務就丟擲異常

 

 4.切點關聯

關聯到上方定義的通知即可。

 

設定回滾事務屬性:

Spring事務管理中異常回滾預設情況下只對RuntimeException有效,非執行時異常是不會回滾的。不過<tx:method>標籤中有兩個屬性可以指定遇到哪種型別的異常時回滾資料:

   

    rollback - for:指定會自動回滾的非執行時異常,IO異常、反射異常、SQL異常等等。

    no - rollback - for:指定不會回滾的執行時異常,空指標、下標越界等等。

   

事務的回滾規則可以通過@Transactional 註解或者配置檔案設定:

1.註解:通過rollbackFor 和 noRollbackFor 屬性來定義。

這兩個屬性被宣告為 Class[] 型別的, 因此可以為這兩個屬性指定多個異常類:

 

在 Spring 2.x 事務通知中, 可以在 <tx:method> 元素中指定回滾規則,如果有不止一種異常, 用逗號分隔:

 

 超時和只讀屬性

由於事務可以在行和表上獲得鎖,因此長事務會佔用資源,並對整體效能產生影響.,

如果一個事務只讀取資料但不做修改,資料庫引擎可以對這個事務進行優化:

超時事務屬性: 事務在強制回滾之前可以保持多久,這樣可以防止長期執行的事務佔用資源

只讀事務屬性: 表示這個事務只讀取資料但不更新資料,這樣可以幫助資料庫引擎優化事務

超時和只讀屬性可以在 @Transactional 註解中定義.超時屬性以秒為單位來計算:

 

  在 Spring 2.x 事務通知中,超時和只讀屬性可以在 <tx:method> 元素中進行指定: