spring事務管理-宣告式事務
阿新 • • 發佈:2019-02-19
spring通過springAOP提供事務支援。可理解spring事務將方法包裝上事務邊界的切面。
spring提供三種方式來宣告事務性邊界。以前通過SpringAOP和TransactionProxyFactoryBean的代理Bean實現宣告式事務。後來更好的宣告式事務是使用spring的tx名稱空間和@Transactional註解。
spring提供了多種宣告式事務的機制,但所有的方式都依賴五中引數控制管理事務策略。
事務的屬性
傳播行為 定義了客戶端與被呼叫方法之間的事務邊界
傳播行為常量
隔離級別
定義了一個事務可能受其他併發事務影響的程度
併發可能會導致出現幾種問題:
隔離級別:
是否只讀
若事務被宣告為只讀,則資料庫會根據事務進行一些優化。
對那些具備啟動一個新事務的傳播行為(PROPAGATION_REQUIRED、PROPAGATION_REQUIRED_NEW、PROPAGATION_NESTED)的方法來說,將事務宣告為只讀才有意義。
另外,如果採用hibernate作為持久化機制,那麼將事務宣告為只讀將會導致hibernate的flush模式將被設定為FLUSH_NEVER。這會告訴hibernate避免和資料庫進行不必要的物件同步,並將所有的更新延遲到事務結束。
事務超時
為了使應用程式很好地執行,事務不能執行太長的時間。因為如果事務的執行時間變得特別長,而事務可能涉及到對後端資料庫的鎖定,所以長時間的事務會不必要地佔用資料庫資源。那麼你可以宣告一個事務,在特定的秒數後自動回滾,而不是等待結束。
因為超時時鐘會在事務開始啟動。所以只有對那些具備可能啟動一個新事務的傳播行為(PROPAGATION_REQUIRED、PROPAGATION_NEW、PROPAGATION_NESTED)的方法來說,宣告事務超市才有意義。
回滾規則
預設情況下事務遇到執行期異常時才會回滾。而遇到檢查型異常時不會回滾。
在xml中定義事務
使用tx的名稱空間,可以避免TransactionProxyFactoryBean冗長的配置檔案。
在xml中宣告事務策略
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="save" propagation="REQUIRED" />
</tx:method name="*" propagation="SUPPORTS" read-only="true" />
<tx:attributes>
</tx:advice>
<tx:method>有多個屬性來幫助定義方法的事務策略
根據約定優於配置,<tx:advice>假定事務管理器被宣告為一個id為transactionManager的bean。如果碰巧為事務管理器配置一個不同的id(如txManager),則需要在transactionManager屬性中明確事務管理器的id:
<tx:advice id="txAdvice" transaction-Manager="txManager">
</tx:advice>
以上的<tx:advice>只是定義了AOP通知,用於把事務邊界通知給方法。但這不是完整事務性切面。為了定義完整事務性切面,我們需要一個通知器(advisor)。如下:
<aop:config>
<aop:advisor pointcut="execution(** ..SpitterService.*.(..))" advice-ref="txAdvice" />
</aop:config>
定義註解驅動的事務
tx名稱空間還提供了<tx:annotation-driven>元素。使用十分簡單:
<tx:annotation-driven />
<tx:annotation-driven>告訴spring檢查上下文中所有的bean並查詢使用@Transactional註解的bean。
對每個使用@Transactional註解的bean,<tx:annotation-driven>會自動為它新增事務。通知的事務屬性是通過@Transactional註解的引數來定義的。
參考資料:《spring 實戰(第三版)》
圖片來自:《spring 實戰(第三版)》
參考資料:《spring 實戰(第三版)》
圖片來自:《spring 實戰(第三版)》