Spring的事務管理機制
本文在<Spring中使用注解進行事務的配置方式>文章的基礎上,一起來學習一下Spring中對事務的支持——Spring的事務管理機制。
Spring對事務管理的支持
與EJB類似,Spring提供了對 編碼式 和 聲明式 事務管理的支持。但是,Spring對事務管理的能力遠遠超過EJB。這里就不詳細介紹編碼式事務和聲明式事務的區別了。有興趣的讀者可以自行Google。
Spring對事務管理是通過事務管理器來實現的。Spring提供了許多內置事務管理器實現:
事務管理器 ( org.springframework.* ) |
使用場景 |
---|---|
jdbc.datasource.DataSourceTransactionManager | 數據源事務管理器,提供對單個 javax.sql.DataSource 事務管理,用于Spring JDBC抽象框架、iBATIS或MyBatis框架的事務管理; |
orm.jdo.JdoTransactionManager | 提供對單個 javax.jdo.PersistenceManagerFactor y事務管理,用于集成JDO框架時的事務管理; |
orm.jpa.JpaTransactionManager | 提供對單個 javax.persistence.EntityManagerFactory 事務支持,用于集成JPA實現框架時的事務管理; |
orm.hibernate3.HibernateTransactionManager | 提供對單個 org.hibernate.SessionFactory 事務支持,用于集成Hibernate框架時的事務管理;該事務管理器只支持Hibernate3+版本,且Spring3.0+版本只支持Hibernate 3.2+版本; |
transaction.jta.JtaTransactionManager | 提供對分布式事務管理的支持,并將事務管理委托給Java EE應用服務器事務管理器; |
transaction.jta.OC4JjtaTransactionManager | Spring提供的對OC4J10.1.3+應用服務器事務管理器的適配器,此適配器用于對應用服務器提供的高級事務的支持; |
transaction.jta.WebSphereUowTransactionManager | Spring提供的對WebSphere 6.0+應用服務器事務管理器的適配器,此適配器用于對應用服務器提供的高級事務的支持; |
transaction.jta.WebLogicJtaTransactionManager | Spring提供的對WebLogic 8.1+應用服務器事務管理器的適配器,此適配器用于對應用服務器提供的高級事務的支持。 |
以上就是Spring中支持使用的事務管理器,一般我們比較常用的就是 HibernateTransactionManager 和 DataSourceTransactionManager 。我們在使用事務的時候要聲明要使用哪種事務管理器。如:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean>
事務屬性
spring中,聲明事務是通過事務屬性來定義的。事務屬性描述了事務策略如何應用到方法上事務屬性包含5個方面:
傳播行為
隔離級別
回滾規則
事務超時
是否只讀
這里簡單介紹一下這五個屬性。
傳播行為
傳播行為定義了客戶端與被調用方法之間的事務邊界,即傳播規則回答了這樣的一個問題,新的事務應該被啟動還是掛起,或者方法是否要在事務環境中運行。(后面會有單獨的文章介紹該屬性)
隔離級別
隔離級別定義了一個事務可能受其他并發事務影響的程度。多事務并發可能會導致臟讀、幻讀、不可重復讀等各種讀現象。(具體參考:數據庫的讀現象淺析)
ISOLATION_DEFAULT:使用后端數據庫默認的規則
ISOLATION_READ_UNCOMMITTED:允許讀取尚未提交的數據變更,可能會導致臟讀,幻讀或不可重復讀
ISOLATION_READ_COMMITTED:允許讀取并發事務已經提交的數據,可以防止臟讀,但是幻讀或不可重復讀仍有可能發生
ISOLATION_REPEATABLE_READ:對同意字段的多次讀取結果是一致的,除非數據是被本事務自己所修改,看阻止臟讀和不可重復讀,但幻讀仍有可能發生
ISOLATIOM_SERIALIZABLE:完全服從ACID的隔離級別,確保阻止臟讀,不可重復讀以及幻讀,這是最慢的數據隔離級別
(具體參考: 深入分析事務的隔離級別 )
是否只讀
如果事務只對后端的數據庫進行讀操作,數據庫可以利用事務ID只讀特性來進行一些特定的優化。通過將事務設置為只讀,你就可以給數據庫一個機會,讓他應用它認為合適的優化措施。因為是否只讀是在事務啟動的時候由數據庫實施的,所以只有對那些具備可能啟動一個新事務的傳播行為( PROPAGATION_REQUIRED , PROPAGATION_REQUIRED_NEW , PROPAGATION_NESTED )的方法來說,才有意義。
事務超時
為了使應用程序很好地運行,事務不能運行太長時間。因為超時時鐘會在事務開始時啟動,所以只有對那些具備可能啟動一個新事務的傳播行為( PROPAGATION_REQUIRED , PROPAGATION_REQUIRED_NEW , PROPAGATION_NESTED )的方法來說,才有意義。
事務回滾
事務回滾規則定義了哪些異常會導致事務回滾而哪些不會。默認情況下,事務只有在遇到運行時期異常才回滾,而在遇到檢查型異常時不會回滾。
配置方式
事務屬性的配置方式通過以下關鍵字來指定:
關鍵字 | 含義 |
---|---|
isolation | 指定事務的隔離級別 |
propagation | 定義事務的傳播規則 |
read-only | 指定事務為只讀 |
rollback-forno-rollback-for | rollback-for指定事務對哪些檢查型異常應當回滾而不提交no-rollback-for指定事務對哪些異常應當繼續執行而不回滾 |
timeout | 對于長時間運行的事務定義超時時間 |
XML中事務屬性的配置方式如下:
<tx:advice id="txAdvice" transactionmanager="transactionManager"> <tx:attributes> <tx:method name="*" propagation="REQUIRED" read-only="true"/> </tx:attributes> </tx:advice>
注解中事務屬性的配置方式如下:
@Transaction(propagation=Propagation. REQUIRED,readOnly=true) public void add(String username){ //... }
總結
事務是企業應用開發中很重要的組成部分,他讓軟件變得更加健壯。他保證了全有或全無的操作。
Spring同時支持編碼式和聲明式事務管理,無論使用哪種方式進行事務管理,都應該知道與事務相關的五個屬性。
(全文完)
來自: http://www.hollischuang.com/archives/1489