本篇文章主要介紹了Spring 使用註解方式進行事務管理配置方式,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧
使用步驟:
步驟一、在spring設定檔中引入
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
步驟二、具有@Transactional 註解的bean自動配置為聲明式事務支援
<!-- 事务管理器配置, Hibernate单数据源事务 --> <bean id="defaultTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- 使用annotation定义事务 --> <tx:annotation-driven transaction-manager="defaultTransactionManager" proxy-target-class="true" />
步驟三、在介面或類別的聲明處,寫一個@Transactional.
要是只在介面上寫, 介面的實作類別就會繼承下來、介面的實作類別的具體方法,可以覆寫類別宣告處的設定
@Transactional //類別級的註解、適用於類別中所有的public的方法
事務的傳播行為和隔離等級
大家在使用spring的註解式事務管理時,對事務的傳播行為和隔離等級可能有點不知所措,下邊就詳細的介紹下以備方便查閱。
事物註解方式: @Transactional
當標於類別前時, 標示類別中所有方法都進行事物處理, 範例:
@Transactional public class TestServiceBean implements TestService {}
當類別中某些方法不需要事物時:
@Transactional public class TestServiceBean implements TestService { private TestDao dao; public void setDao(TestDao dao) { this.dao = dao; } @Transactional(propagation = Propagation.NOT_SUPPORTED) public List<Object> getAll() { return null; } }
事物傳播行為介紹:
@Transactional(propagation=Propagation.REQUIRED)
如果有事務, 那麼加入事務, 沒有的話新建一個(預設)
#@Transactional(propagation=Propagation.NOT_SUPPORTED)
#容器不會為這個方法開啟事務
@Transactional(propagation=Propagation.REQUIRES_NEW)
不管是否存在事務,都創建一個新的事務,原來的掛起,新的執行完畢,繼續執行老的事務
@Transactional(propagation=Propagation.MANDATORY)
必須在一個已有的事務中執行,否則拋出異常
@Transactional(propagation=Propagation.NEVER)
必須在一個沒有的事務中執行,否則拋出異常(與Propagation.MANDATORY相反)
@Transactional(propagation=Propagation.SUPPORTS)
如果其他bean調用這個方法,在其他bean中聲明事務,那就用事務.如果其他bean沒有聲明事務,那就不用事務.
事物超時設定:
#@Transactional(timeout=30) //預設是30秒
交易隔離等級:
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
讀取未提交資料(會出現髒讀, 不可重複讀取) 基本上不使用
@Transactional(isolation = Isolation.READ_COMMITTED)
讀取已提交資料(會出現不可重複讀取和幻讀)
#@Transactional(isolation = Isolation.REPEATABLE_READ)
#可重複讀取(會發生幻讀)
@Transactional(isolation = Isolation.SERIALIZABLE)
MYSQL: 預設為REPEATABLE_READ層級 | SQLSERVER: 預設為READ_COMMITTED 髒讀: 一個事務讀取到另一交易未提交的更新資料 |
#後續讀取可以讀到另一事務已提交的更新資料. 相反, "可重複讀"在同一事務中多次 | 讀取資料時, 能夠保證所讀資料一樣, 也就是後續讀取不能讀到另一事務已提交的更新資料 |
@Transactional註解中常用參數說明 | 參數名稱#功能描述 |
續表)
參數名稱 | 功能描述 |
#rollbackForClassName | #該屬性用於設定需要進行回滾的異常類別名稱數組,當方法中拋出指定異常名稱數組中的異常時,則進行事務回滾。例如: 指定單一異常類別名稱:@Transactional(rollbackForClassName="RuntimeException") 指定多個例外類別名稱:@Transactional (rollbackForClassName={"RuntimeException","Exception"}) |
noRollbackFor | |
| 此屬性用於設定不需要進行回滾的異常類別數組,當方法中拋出指定異常數組中的異常時,不進行交易回滾。例如:指定單一異常類別:@Transactional(noRollbackFor=RuntimeException.class) 指定多個例外:@Transactional(noRollbackFor ={RuntimeException.class, Exception.class}) #noRollbackForClassName |
#此屬性用於設定不需要進行回滾的異常類別名稱數組,當方法中拋出指定異常名稱數組中的異常時,不進行交易回滾。例如: 指定單一異常類別名稱:@Transactional(noRollbackForClassName="RuntimeException") | |
指定多個例外類別名稱: @Transactional(noRollbackForClassName={"RuntimeException","Exception"}) |
注意的几点:
1 @Transactional 只能被应用到public方法上, 对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能.
2用 spring 事务管理器,由spring来负责数据库的打开,提交,回滚.默认遇到运行期例外(throw new RuntimeException("注释");)会回滚,即遇到不受检查(unchecked)的例外时回滚;而遇到需要捕获的例外(throw new Exception("注释");)不会回滚,即遇到受检查的例外(就是非运行时抛出的异常,编译器会检查到的异常叫受检查例外或说受检查异常)时,需我们指定方式来让事务回滚 要想所有异常都回滚,要加上 @Transactional( rollbackFor={Exception.class,其它异常}) .如果让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)
如下:
@Transactional(rollbackFor=Exception.class) //指定回滚,遇到异常Exception时回滚 public void methodName() { throw new Exception("注释"); } @Transactional(noRollbackFor=Exception.class)//指定不回滚,遇到运行期例外(throw new RuntimeException("注释");)会回滚 public ItimDaoImpl getItemDaoImpl() { throw new RuntimeException("注释"); }
3、@Transactional 注解应该只被应用到 public 可见度的方法上。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错, 但是这个被注解的方法将不会展示已配置的事务设置。
4、@Transactional 注解可以被应用于接口定义和接口方法、类定义和类的 public 方法上。然而,请注意仅仅 @Transactional 注解的出现不足于开启事务行为,它仅仅 是一种元数据,能够被可以识别 @Transactional 注解和上述的配置适当的具有事务行为的beans所使用。上面的例子中,其实正是
5、Spring团队的建议是你在具体的类(或类的方法)上使用 @Transactional 注解,而不要使用在类所要实现的任何接口上。你当然可以在接口上使用 @Transactional 注解,但是这将只能当你设置了基于接口的代理时它才生效。因为注解是 不能继承 的,这就意味着如果你正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装(将被确认为严重的)。因 此,请接受Spring团队的建议并且在具体的类上使用 @Transactional 注解。
以上是Spring使用註解方式進行事務管理設定方式的實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!