首頁  >  文章  >  Java  >  Spring使用註解方式進行事務管理設定方式的實例詳解

Spring使用註解方式進行事務管理設定方式的實例詳解

Y2J
Y2J原創
2017-05-02 11:47:471519瀏覽

本篇文章主要介紹了Spring 使用註解方式進行事務管理配置方式,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧

使用步驟:

步驟一、在spring設定檔中引入cc2c39e2370aac9d3896793edbbe786f命名空間

<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)






##都##序列化 無法重複讀取: 在同一交易中, 多次讀取相同資料回傳的結果有所不同, 換句話說, 幻讀: 一個事務讀到另一個事務已提交的insert資料

MYSQL: 預設為REPEATABLE_READ層級

SQLSERVER: 預設為READ_COMMITTED

髒讀: 一個事務讀取到另一交易未提交的更新資料

#後續讀取可以讀到另一事務已提交的更新資料. 相反, "可重複讀"在同一事務中多次

讀取資料時, 能夠保證所讀資料一樣, 也就是後續讀取不能讀到另一事務已提交的更新資料

@Transactional註解中常用參數說明

參數名稱

#功能描述
## ####readOnly############此屬性用於設定目前事務是否為唯讀事務,設定為true表示唯讀,false則表示可讀寫,預設值為false。例如:@Transactional(readOnly=true)###################rollbackFor############該屬性用於設定需要進行回滾的異常類別數組,當方法中拋出指定異常數組中的異常時,則進行交易回滾。例如:######指定單一異常類別:@Transactional(rollbackFor=RuntimeException.class)######指定多個異常類別:@Transactional(rollbackFor={RuntimeException.class, Exception.class})# ##############

 續表)

此屬性用於設定不需要進行回滾的異常類別數組,當方法中拋出指定異常數組中的異常時,不進行交易回滾。例如:#propagation

參數名稱

功能描述

#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"})

############此屬性用於設定交易的傳播行為,具體取值可參考表6-7。 ############例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)######################## #isolation##################該屬性用於設定底層資料庫的事務隔離級別,事務隔離級別用於處理多事務並發的情況,通常使用資料庫的預設隔離等級即可,基本上不需要進行設定#########################timeout################# ##此屬性用於設定交易的逾時秒數,預設值為-1表示永不逾時###################

 注意的几点:

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所使用。上面的例子中,其实正是 9e4580300b4ee94180ae502c8f21c1b3元素的出现 开启 了事务行为。

5、Spring团队的建议是你在具体的类(或类的方法)上使用 @Transactional 注解,而不要使用在类所要实现的任何接口上。你当然可以在接口上使用 @Transactional 注解,但是这将只能当你设置了基于接口的代理时它才生效。因为注解是 不能继承 的,这就意味着如果你正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装(将被确认为严重的)。因 此,请接受Spring团队的建议并且在具体的类上使用 @Transactional 注解。

以上是Spring使用註解方式進行事務管理設定方式的實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn