SpringBoot事務註解@Transactional

SpringBoot提供了很是方便的事務操做,經過註解就能夠實現事務的回滾,很是方便快捷,下面咱們就說一下如何進行事務操做。java

1. 事務說明

在Spring中,事務有兩種實現方式,分別是編程式事務管理和聲明式事務管理兩種方式。
編程式事務管理: 編程式事務管理使用TransactionTemplate或者直接使用底層的PlatformTransactionManager。對於編程式事務管理,spring推薦使用TransactionTemplate。
聲明式事務管理: 創建在AOP之上的。其本質是對方法先後進行攔截,而後在目標方法開始以前建立或者加入一個事務,在執行完目標方法以後根據執行狀況提交或者回滾事務。
聲明式事務管理不須要入侵代碼,經過@Transactional就能夠進行事務操做,更快捷並且簡單。推薦使用spring

2. 如何使用

在Mybatis中使用事務,很是簡單,只須要在函數增長註解@Transactional,無需任何配置。咱們經過在controller層增長事務例子看下:數據庫

@Autowired
OrderServiceorderService;   //order操做的Service層

@ApiOperation(value = "增長OrderCustomer")
@RequestMapping(value = "", method = RequestMethod.POST)
@ResponseBody
@Transactional
public JsonBean<Order> insertOrder(@RequestParam(value = "order") String order) {
try {
//建立訂單
Order order = orderService.insert(user.getId(),is_company,fk_want_company_id);
return new JsonBean(SUCCESS, orderCustomer);
}
catch (ErrorCodeException e)
{
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return new JsonBean(e.getErrorCode());
}
}

@Transactional能夠做用於接口、接口方法、類以及類方法上。看成用於類上時,該類的全部 public 方法將都具備該類型的事務屬性,同時,咱們也能夠在方法級別使用該標註來覆蓋類級別的定義。所以能夠在Service層和Controller層使用,上述例子咱們在Controller層實現,咱們模擬了一個訂單提交的接口,其中JsonBean是統一返回錯誤碼基類,ErrorCodeException是自定義異常。編程

  1. 經過@Transactional,實現了事務操做。
  2. Spring的AOP即聲明式事務管理默認是針對unchecked exception回滾。也就是默認對RuntimeException()異常或是其子類進行事務回滾;checked異常,即Exception可try{}捕獲的不會回滾,所以對於咱們自定義異常,經過rollbackFor進行設定,後續會單獨講
  3. 若是咱們須要捕獲異常後,同時進行回滾,經過TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();進行手動回滾操做。
  4. 使用Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
    設置回滾點,使用TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);回滾到savePoint。

3.經常使用配置

參 數 名 稱 功 能 描 述
readOnly 該屬性用於設置當前事務是否爲只讀事務,設置爲true表示只讀,false則表示可讀寫,默認值爲false。例如:@Transactional(readOnly=true)
rollbackFor 該屬性用於設置須要進行回滾的異常類數組,當方法中拋出指定異常數組中的異常時,則進行事務回滾。例如:指定單一異常類:@Transactional(rollbackFor=RuntimeException.class)指定多個異常類:@Transactional(rollbackFor={RuntimeException.class, Exception.class})
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」})
propagation 該屬性用於設置事務的傳播行爲。例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
isolation 該屬性用於設置底層數據庫的事務隔離級別,事務隔離級別用於處理多事務併發的狀況,一般使用數據庫的默認隔離級別便可,基本不須要進行設置
timeout 該屬性用於設置事務的超時秒數,默認值爲-1表示永不超時

4. 事務屬性

事務隔離級別
隔離級別是指若干個併發的事務之間的隔離程度。TransactionDefinition 接口中定義了五個表示隔離級別的常量:數組

TransactionDefinition.ISOLATION_DEFAULT:這是默認值,表示使用底層數據庫的默認隔離級別。對大部分數據庫而言,一般這值就是TransactionDefinition.ISOLATION_READ_COMMITTED。
TransactionDefinition.ISOLATION_READ_UNCOMMITTED:該隔離級別表示一個事務能夠讀取另外一個事務修改但尚未提交的數據。該級別不能防止髒讀,不可重複讀和幻讀,所以不多使用該隔離級別。好比PostgreSQL實際上並無此級別。
TransactionDefinition.ISOLATION_READ_COMMITTED:該隔離級別表示一個事務只能讀取另外一個事務已經提交的數據。該級別能夠防止髒讀,這也是大多數狀況下的推薦值。
TransactionDefinition.ISOLATION_REPEATABLE_READ:該隔離級別表示一個事務在整個過程當中能夠屢次重複執行某個查詢,而且每次返回的記錄都相同。該級別能夠防止髒讀和不可重複讀。
TransactionDefinition.ISOLATION_SERIALIZABLE:全部的事務依次逐個執行,這樣事務之間就徹底不可能產生干擾,也就是說,該級別能夠防止髒讀、不可重複讀以及幻讀。可是這將嚴重影響程序的性能。一般狀況下也不會用到該級別。markdown

事務傳播行爲
所謂事務的傳播行爲是指,若是在開始當前事務以前,一個事務上下文已經存在,此時有若干選項能夠指定一個事務性方法的執行行爲。在TransactionDefinition定義中包括了以下幾個表示傳播行爲的常量:併發

TransactionDefinition.PROPAGATION_REQUIRED:若是當前存在事務,則加入該事務;若是當前沒有事務,則建立一個新的事務。這是默認值。
TransactionDefinition.PROPAGATION_REQUIRES_NEW:建立一個新的事務,若是當前存在事務,則把當前事務掛起。
TransactionDefinition.PROPAGATION_SUPPORTS:若是當前存在事務,則加入該事務;若是當前沒有事務,則以非事務的方式繼續運行。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事務方式運行,若是當前存在事務,則把當前事務掛起。
TransactionDefinition.PROPAGATION_NEVER:以非事務方式運行,若是當前存在事務,則拋出異常。
TransactionDefinition.PROPAGATION_MANDATORY:若是當前存在事務,則加入該事務;若是當前沒有事務,則拋出異常。
TransactionDefinition.PROPAGATION_NESTED:若是當前存在事務,則建立一個事務做爲當前事務的嵌套事務來運行;若是當前沒有事務,則該取值等價於TransactionDefinition.PROPAGATION_REQUIRED。app

事務超時
所謂事務超時,就是指一個事務所容許執行的最長時間,若是超過該時間限制但事務尚未完成,則自動回滾事務。在 TransactionDefinition 中以 int 的值來表示超時時間,其單位是秒。
默認設置爲底層事務系統的超時值,若是底層數據庫事務系統沒有設置超時值,那麼就是none,沒有超時限制。函數

事務只讀屬性
只讀事務用於客戶代碼只讀但不修改數據的情形,只讀事務用於特定情景下的優化,好比使用Hibernate的時候。
默認爲讀寫事務。性能

相關文章
相關標籤/搜索