spring的@Transactional註解詳細用法
概述
事務管理對於企業應用來說是至關重要的,即使出現異常情況,它也可以保證資料的一致性。
Spring Framework對事務管理提供了一致的抽象,其特點如下:
- 為不同的事務API提供一致的程式設計模型,比如JTA(Java Transaction API), JDBC, Hibernate, JPA(Java Persistence API和JDO(Java Data Objects)
- 支援宣告式事務管理,特別是基於註解的宣告式事務管理,簡單易用
- 提供比其他事務API如JTA更簡單的程式設計式事務管理API
- 與spring資料訪問抽象的完美整合
事務管理方式
spring支援程式設計式事務管理和宣告式事務管理兩種方式。
程式設計式事務管理使用TransactionTemplate或者直接使用底層的PlatformTransactionManager。對於程式設計式事務管理,spring推薦使用TransactionTemplate。
宣告式事務管理建立在AOP之上的。其本質是對方法前後進行攔截,然後在目標方法開始之前建立或者加入一個事務,在執行完目標方法之後根據執行情況提交或者回滾事務。宣告式事務最大的優點就是不需要通過程式設計的方式管理事務,這樣就不需要在業務邏輯程式碼中摻雜事務管理的程式碼,只需在配置檔案中做相關的事務規則宣告(或通過基於@Transactional註解的方式),便可以將事務規則應用到業務邏輯中。
顯然宣告式事務管理要優於程式設計式事務管理,這正是spring倡導的非侵入式的開發方式。宣告式事務管理使業務程式碼不受汙染,一個普通的POJO物件,只要加上註解就可以獲得完全的事務支援。和程式設計式事務相比,宣告式事務唯一不足地方是,後者的最細粒度只能作用到方法級別,無法做到像程式設計式事務那樣可以作用到程式碼塊級別。但是即便有這樣的需求,也存在很多變通的方法,比如,可以將需要進行事務管理的程式碼塊獨立為方法等等。
宣告式事務管理也有兩種常用的方式,一種是基於tx和aop名字空間的xml配置檔案,另一種就是基於@Transactional註解。顯然基於註解的方式更簡單易用,更清爽。
自動提交(AutoCommit)與連線關閉時的是否自動提交
自動提交
預設情況下,資料庫處於自動提交模式。每一條語句處於一個單獨的事務中,在這條語句執行完畢時,如果執行成功則隱式的提交事務,如果
執行失敗則隱式的回滾事務。
對於正常的事務管理,是一組相關的操作處於一個事務之中,因此必須關閉資料庫的自動提交模式。不過,這個我們不用擔心,spring會將底層連線的自動提交特性設定為false。
org/springframework/jdbc/datasource/DataSourceTransactionManager.java
1 // switch to manual commit if necessary. this is very expensive in some jdbc drivers, 2 // so we don't want to do it unnecessarily (for example if we've explicitly 3 // configured the connection pool to set it already). 4 if (con.getautocommit()) { 5 txobject.setmustrestoreautocommit(true); 6 if (logger.isdebugenabled()) { 7 logger.debug("switching jdbc connection [" + con + "] to manual commit"); 8 } 9 con.setautocommit(false); 10 }
有些資料連線池提供了關閉事務自動提交的設定,最好在設定連線池時就將其關閉。但C3P0沒有提供這一特性,只能依靠spring來設定。
因為JDBC規範規定,當連線物件建立時應該處於自動提交模式,這是跨DBMS的預設值,如果需要,必須顯式的關閉自動提交。C3P0遵守這一規範,讓客戶程式碼來顯式的設定需要的提交模式。
連線關閉時的是否自動提交
當一個連線關閉時,如果有未提交的事務應該如何處理?JDBC規範沒有提及,C3P0預設的策略是回滾任何未提交的事務。這是一個正確的策略,但JDBC驅動提供商之間對此問題並沒有達成一致。
C3P0的autoCommitOnClose屬性預設是false,沒有十分必要不要動它。或者可以顯式的設定此屬性為false,這樣會更明確。
基於註解的宣告式事務管理配置
spring-servlet.xml
1 <!-- transaction support--> 2 <!-- PlatformTransactionMnager --> 3 <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 4 <property name="dataSource" ref="dataSource" /> 5 </bean> 6 <!-- enable transaction annotation support --> 7 <tx:annotation-driven transaction-manager="txManager" />
還要在spring-servlet.xml中新增tx名字空間
1 ... 2 xmlns:tx="http://www.springframework.org/schema/tx" 3 xmlns:aop="http://www.springframework.org/schema/aop" 4 xsi:schemaLocation=" 5 ... 6 7 http://www.springframework.org/schema/tx 8 9 10 http://www.springframework.org/schema/tx/spring-tx.xsd 11 12 ...
MyBatis自動參與到spring事務管理中,無需額外配置,只要org.mybatis.spring.SqlSessionFactoryBean引用的資料來源與DataSourceTransactionManager引用的資料來源一致即可,否則事務管理會不起作用。
另外需要下載依賴包aopalliance.jar放置到WEB-INF/lib目錄下。否則spring初始化時會報異常
java.lang.NoClassDefFoundError: org/aopalliance/intercept/MethodInterceptor
spring事務特性
spring所有的事務管理策略類都繼承自org.springframework.transaction.PlatformTransactionManager介面
1 public interface PlatformTransactionManager { 2 3 TransactionStatus getTransaction(TransactionDefinition definition) 4 throws TransactionException; 5 6 void commit(TransactionStatus status) throws TransactionException; 7 8 void rollback(TransactionStatus status) throws TransactionException; 9 }
其中TransactionDefinition介面定義以下特性:
事務隔離級別
隔離級別是指若干個併發的事務之間的隔離程度。TransactionDefinition 介面中定義了五個表示隔離級別的常量:
- TransactionDefinition.ISOLATION_DEFAULT:這是預設值,表示使用底層資料庫的預設隔離級別。對大部分資料庫而言,通常這值就是TransactionDefinition.ISOLATION_READ_COMMITTED。
- TransactionDefinition.ISOLATION_READ_UNCOMMITTED:該隔離級別表示一個事務可以讀取另一個事務修改但還沒有提交的資料。該級別不能防止髒讀,不可重複讀和幻讀,因此很少使用該隔離級別。比如PostgreSQL實際上並沒有此級別。
- TransactionDefinition.ISOLATION_READ_COMMITTED:該隔離級別表示一個事務只能讀取另一個事務已經提交的資料。該級別可以防止髒讀,這也是大多數情況下的推薦值。
- TransactionDefinition.ISOLATION_REPEATABLE_READ:該隔離級別表示一個事務在整個過程中可以多次重複執行某個查詢,並且每次返回的記錄都相同。該級別可以防止髒讀和不可重複讀。
- TransactionDefinition.ISOLATION_SERIALIZABLE:所有的事務依次逐個執行,這樣事務之間就完全不可能產生干擾,也就是說,該級別可以防止髒讀、不可重複讀以及幻讀。但是這將嚴重影響程式的效能。通常情況下也不會用到該級別。
事務傳播行為
所謂事務的傳播行為是指,如果在開始當前事務之前,一個事務上下文已經存在,此時有若干選項可以指定一個事務性方法的執行行為。在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。
事務超時
所謂事務超時,就是指一個事務所允許執行的最長時間,如果超過該時間限制但事務還沒有完成,則自動回滾事務。在 TransactionDefinition 中以 int 的值來表示超時時間,其單位是秒。
預設設定為底層事務系統的超時值,如果底層資料庫事務系統沒有設定超時值,那麼就是none,沒有超時限制。
事務只讀屬性
只讀事務用於客戶程式碼只讀但不修改資料的情形,只讀事務用於特定情景下的優化,比如使用Hibernate的時候。
預設為讀寫事務。
spring事務回滾規則
指示spring事務管理器回滾一個事務的推薦方法是在當前事務的上下文內丟擲異常。spring事務管理器會捕捉任何未處理的異常,然後依據規則決定是否回滾丟擲異常的事務。
預設配置下,spring只有在丟擲的異常為執行時unchecked異常時才回滾該事務,也就是丟擲的異常為RuntimeException的子類(Errors也會導致事務回滾),而丟擲checked異常則不會導致事務回滾。
可以明確的配置在丟擲那些異常時回滾事務,包括checked異常。也可以明確定義那些異常丟擲時不回滾事務。
還可以程式設計性的通過setRollbackOnly()方法來指示一個事務必須回滾,在呼叫完setRollbackOnly()後你所能執行的唯一操作就是回滾。
@Transactional註解
@Transactional屬性
屬性 | 型別 | 描述 |
---|---|---|
value | String | 可選的限定描述符,指定使用的事務管理器 |
propagation | enum: Propagation | 可選的事務傳播行為設定 |
isolation | enum: Isolation | 可選的事務隔離級別設定 |
readOnly | boolean | 讀寫或只讀事務,預設讀寫 |
timeout | int (in seconds granularity) | 事務超時時間設定 |
rollbackFor | Class物件陣列,必須繼承自Throwable | 導致事務回滾的異常類陣列 |
rollbackForClassName | 類名陣列,必須繼承自Throwable | 導致事務回滾的異常類名字陣列 |
noRollbackFor | Class物件陣列,必須繼承自Throwable | 不會導致事務回滾的異常類陣列 |
noRollbackForClassName | 類名陣列,必須繼承自Throwable | 不會導致事務回滾的異常類名字陣列 |
用法
@Transactional 可以作用於介面、介面方法、類以及類方法上。當作用於類上時,該類的所有 public 方法將都具有該型別的事務屬性,同時,我們也可以在方法級別使用該標註來覆蓋類級別的定義。
雖然 @Transactional 註解可以作用於介面、介面方法、類以及類方法上,但是 Spring 建議不要在介面或者介面方法上使用該註解,因為這隻有在使用基於介面的代理時它才會生效。另外, @Transactional 註解應該只被應用到 public 方法上,這是由 Spring AOP 的本質決定的。如果你在 protected、private 或者預設可見性的方法上使用 @Transactional 註解,這將被忽略,也不會丟擲任何異常。
預設情況下,只有來自外部的方法呼叫才會被AOP代理捕獲,也就是,類內部方法呼叫本類內部的其他方法並不會引起事務行為,即使被呼叫方法使用@Transactional註解進行修飾。
1 @Transactional(readOnly = true) 2 public class DefaultFooService implements FooService { 3 4 public Foo getFoo(String fooName) { 5 // do something 6 } 7 8 // these settings have precedence for this method 9 //方法上註解屬性會覆蓋類註解上的相同屬性 10 @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) 11 public void updateFoo(Foo foo) { 12 // do something 13 } 14 }
相關推薦
spring的@Transactional註解詳細用法
概述 事務管理對於企業應用來說是至關重要的,即使出現異常情況,它也可以保證資料的一致性。Spring Framework對事務管理提供了一致的抽象,其特點如下: 為不同的事務API提供一致的程式設計模型,比如JTA(Java Transaction API), JDBC, Hibernate, JPA
spring @Transactional註解參數詳解
正是 SQ com package don ted {} 說明 mda 事物註解方式: @Transactional 當標於類前時, 標示類中所有方法都進行事物處理 , 例子: @Transactional public class TestServiceBea
spring @Transactional註解參數詳解(13)
基於接口 ack -a 事物 null span ports readonly 可見度 事物註解方式: @Transactional 當標於類前時, 標示類中所有方法都進行事物處理 , 例子: 1 @Transactional public class TestServ
數據庫事務中的隔離級別和鎖+spring Transactional註解
遇到 丟失更新 讀鎖 討論 acid 通過 行修改 nal dbms 數據庫事務中的隔離級別和鎖 數據庫事務在後端開發中占非常重要的地位,如何確保數據讀取的正確性、安全性也是我們需要研究的問題。 ACID 首先總結一下數據庫事務正確執行的四個要素(ACID): 原子性(At
程式碼丟擲異常後進行事務回滾的兩種方式(Spring @Transactional註解)
需求 在service層的某個方法中,在執行完一個對資料庫的寫方法後,丟擲異常,再執行另一個對資料庫的寫方法,虛擬碼如下: @Transactional public void func() { dao.write(pojo1); throw new Exception("異常"
Spring Transactional註解
前言 使用@Transactional 註解有一段時間了,今天來對它進行下總結。 再說這個之前先說下事務。 事務的基本要素(ACID) 原子性(Atomicity):事務開始後所有操作,要麼全部做完,要麼全部不做,不可能停滯在中間環節。事務執行過程中出錯,會
spring @Transactional 註解引數概要
1.可配置的引數列表 屬性 型別 描述 傳播性 列舉型:Propagation 可選的傳播性設定 隔離性 列舉型:Isolation 可選的隔離性級別(預設值:ISOLATION_DEFAULT) 只讀性 布林型
資料庫事務中的隔離級別、鎖、spring Transactional註解
資料庫事務中的隔離級別和鎖 資料庫事務在後端開發中佔非常重要的地位,如何確保資料讀取的正確性、安全性也是我們需要研究的問題。 ACID 首先總結一下資料庫事務正確執行的四個要素(ACID): 原子性(Atomicity):即事務是不可分割的最小工作單元,事務內的操作要麼全做,要麼全
spring @Transactional註解引數詳解
事物註解方式: @Transactional 當標於類前時, 標示類中所有方法都進行事物處理 , 例子: @Transactional public class TestServiceBean implements TestService {} 當類中某些
資料庫Transactional註解的用法,由問題【方法【xxxx】需要在Transactional註解指定rollbackFor或者在方法中顯示的rollback】引入
java阿里巴巴規範提示:方法【xxxx】需要在Transactional註解指定rollbackFor或者在方法中顯示的rollback。先來看看異常的分類error是一定會回滾的這裡Exception是異常,他又分為執行時異常RuntimeException和非執行時異常
Spring的註解@Qualifier用法,以及什麼時候用?
本章講一下@Qualifier註解的用法。以及報的一個錯誤org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeInfoControl':
Spring @Transactional註解使用注意事項
1 注意設定rollbackFor屬性,很多部落格說預設只有RuntimeExcetion會觸發回滾,經驗證確實如此,所以rollbackFor最好應該設定如下:rollbackFor = {Exception.class},當然具體業務具體處理,可能有的業務丟擲的某些異常
Spring @Transactional註解不回滾不起作用無效
原文地址:http://www.cnblogs.com/wuxiaofeng/p/6819209.html 這幾天在專案裡面發現我使用@Transactional之後,拋了異常居然不回滾。後來終於找到了原因。 如果你也出現了這種情況,可以從下面開始排查。 一、特性
spring @Transactional註解用於事務回滾案例
這裡基於小編的這篇博文的spring配置和實體類,service類為基礎,解釋@Transactional註解: 注意這裡@Transcational註解起作用的前提是要使用spring的宣告式事務: <!-- 配置宣告式事務 --> <
spring AOP pointcut 詳細用法
1.首先這是我幾天來對切面的程式設計的理解,之前有稍微學了下 spring切面的程式設計,spring中事物處理常常與pointcut相結合。 pointcut的註解型別 表示式 我就不多說了 。具體可以看spring文件的第199頁~200頁,都比較簡單。 大體上是這樣
Spring註解詳細
組件 ostc use stc 註入 pac 管理 類名 初始 [email protected]/* */ 控制器(註入服務) [email protected]/* */ 服務(註入dao) [email protected]/* *
Spring+Mybatis @Transactional註解事務不生效
排除 context mage prop span 文件 action aso eight @Transactional聲明式事務配置: <bean id="transactionManager" class="org.springframework.j
spring 中註解的詳細解釋之@Responsebody與@RequestBody
可用 gif com .com profile 而是 ping get orm 1、@responseBoby @Responsebody與@RequestBody 一、預備知識:@RequestMapping RequestMapping是一個用來處理請求地
spring,mybatis事務管理配置與@Transactional註解使用[轉]
exception true throws r.java 存在 隔離 enc prot 底層 spring,mybatis事務管理配置與@Transactional註解使用 概述事務管理對於企業應用來說是至關重要的,即使出現異常情況,它也可以保證數據的一致性。Sprin
Spring常用註解用法總結
ams 依賴 對象 strong 設置 osi puts 渲染 多個 轉自http://www.cnblogs.com/leskang/p/5445698.html 1、@Controller 在SpringMVC 中,控制器Controller 負責處理由Dispatch