1. 程式人生 > >Spring 宣告事務中transactionAttributes屬性 +

Spring 宣告事務中transactionAttributes屬性 +

下面是一段典型的spring 宣告事務的配置:

檢視文字列印?
  1. <beanid="userDAOProxy"
  2.     class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  3.     <propertyname="transactionManager">
  4.         <refbean="transactionManager"/>
  5.     </property>
  6.     <propertyname="target">
  7.         <
    reflocal="userDAO"/>
  8.     </property>
  9.     <propertyname="transactionAttributes">
  10.         <props>
  11.             <propkey="insert*">PROPAGATION_REQUIRED</prop>
  12.             <propkey="get*">PROPAGATION_REQUIRED,readOnly</prop>
  13.             <propkey="save*">PROPAGATION_REQUIRED,-ApplicationException,+BusinessException
    </prop>
  14.         </props>
  15.     </property>
  16. </bean>

在Spring宣告事務中,我們可以自定義方法的哪些Exception需要回滾,哪些Exception可以直接提交。

通過下面的配置:

檢視文字列印?
  1. <propkey="save*">PROPAGATION_REQUIRED,-ApplicationException,+BusinessException</prop>

- 表示丟擲該異常時需要回滾

+表示即使丟擲該異常事務同樣要提交

-ApplicationException :表示丟擲ApplicationException 時,事務

需要回滾。但不是說只丟擲ApplicationException 異常時,事務才回滾,如果程式丟擲RuntimeException和Error時,事務一樣會回滾,即使這裡沒有配置。因為Spring中預設對所有的RuntimeException和Error都會回滾事務

Spring中是如何實現這段邏輯的:

呼叫的是

org.springframework.transaction.interceptor.RuleBasedTransactionAttribute.rollbackOn(Throwable ex)

檢視文字列印?
  1. publicboolean rollbackOn(Throwable ex) {  
  2.         if (logger.isTraceEnabled()) {  
  3.             logger.trace("Applying rules to determine whether transaction should rollback on " + ex);  
  4.         }  
  5.         RollbackRuleAttribute winner = null;  
  6.         int deepest = Integer.MAX_VALUE;  
  7.         //配置檔案中的回滾異常列表,當然去掉了-,只有name,commit的規則是另外一個物件
  8.         if (this.rollbackRules != null) {  
  9.             for (RollbackRuleAttribute rule : this.rollbackRules) {  
  10.                 //使用丟擲exception的className(全路徑className)進行indexOf match
  11.                 //如果沒有match上會繼續搜尋superClass name進行match,到Throwable class為止
  12.                 int depth = rule.getDepth(ex);  
  13.                 if (depth >= 0 && depth < deepest) {  
  14.                     deepest = depth;  
  15.                     winner = rule;  
  16.                 }  
  17.             }  
  18.         }  
  19.         if (logger.isTraceEnabled()) {  
  20.             logger.trace("Winning rollback rule is: " + winner);  
  21.         }  
  22.         // User superclass behavior (rollback on unchecked) if no rule matches.
  23.         if (winner == null) {  
  24.             logger.trace("No relevant rollback rule found: applying default rules");  
  25.             //如果沒有match上,呼叫此方法繼續match,判斷instance of RuntimeException or Error
  26.             returnsuper.rollbackOn(ex);  
  27.         }  
  28.         return !(winner instanceof NoRollbackRuleAttribute);  
  29.     }  

rule.getDepth方法程式碼

        因為使用的是className的全路徑進行indexOf匹配,所以如果自定義異常是:com.abc.ApplicationException,你在xml配置檔案中定義為:-abc,同樣會match上,事務也會回滾,這一點需要注意。

       另外一點,如何在xml中定義的是-Exception,這樣只要class的全路徑中包含Exception欄位,如包名,也會匹配上。

檢視文字列印?
  1. publicint getDepth(Throwable ex) {  
  2.     return getDepth(ex.getClass(), 0);  
  3. }  
  4. privateint getDepth(Class exceptionClass, int depth) {  
  5.     if (exceptionClass.getName().indexOf(this.exceptionName) != -1) {  
  6.         // Found it!
  7.         return depth;  
  8.     }  
  9.     // If we've gone as far as we can go and haven't found it...
  10.     if (exceptionClass.equals(Throwable.class)) {  
  11.         return -1;  
  12.     }  
  13.     return getDepth(exceptionClass.getSuperclass(), depth + 1);  
  14. }  

super.rollbackOn(Throwable ex) 方法程式碼

很簡單的一行程式碼,這就是為什麼RuntimeException和Error也會回滾啦。

檢視文字列印?
  1. publicboolean rollbackOn(Throwable ex) {  
  2.         return (ex instanceof RuntimeException || ex instanceof Error);  
  3.     }  

幾次測試輸出的debug日誌

[plain] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1. [08/24 03:35:39] [DEBUG] RuleBasedTransactionAttribute: Applying rules to determine whether transaction should rollback on usertest.exception.BusinessException: Error  
  2. [08/24 03:35:39] [DEBUG] RuleBasedTransactionAttribute: Winning rollback rule is: RollbackRuleAttribute with pattern [BusinessException]  
  3. [08/24 03:35:39] [DEBUG] DataSourceTransactionManager: Triggering beforeCompletion synchronization  
  4. [08/24 03:35:39] [DEBUG] DataSourceTransactionManager: Initiating transaction rollback  
  5. [08/24 03:35:39] [DEBUG] DataSourceTransactionManager: Rolling back JDBC transaction on Connection [[email protected]]  
  6. [08/24 03:35:39] [DEBUG] DataSourceTransactionManager: Triggering afterCompletion synchronization  
  7. [08/24 03:35:39] [DEBUG] TransactionSynchronizationManager: Clearing transaction synchronization  
  8. [08/24 03:35:39] [DEBUG] TransactionSynchronizationManager: Removed value [[email protected]] for key [[email protected]] from thread [main]  
  9. [08/24 03:35:39] [DEBUG] DataSourceTransactionManager: Releasing JDBC Connection [[email protected]] after transaction  
  10. [08/24 03:35:39] [DEBUG] DataSourceUtils: Returning JDBC Connection to DataSource  
  11. [08/24 03:39:16] [DEBUG] TransactionInterceptor: Completing transaction for [usertest.dao.UsersDAO.testInsertAndUpdate] after exception: java.lang.Exception: Error  
  12. [08/24 03:39:16] [DEBUG] RuleBasedTransactionAttribute: Applying rules to determine whether transaction should rollback on java.lang.Exception: Error  
  13. [08/24 03:39:16] [DEBUG] RuleBasedTransactionAttribute: Winning rollback rule is: null  
  14. [08/24 03:39:16] [DEBUG] RuleBasedTransactionAttribute: No relevant rollback rule found: applying superclass default  
  15. [08/24 03:39:16] [DEBUG] DataSourceTransactionManager: Triggering beforeCommit synchronization  
  16. [08/24 03:39:16] [DEBUG] DataSourceTransactionManager: Triggering beforeCompletion synchronization  
  17. [08/24 03:39:16] [DEBUG] DataSourceTransactionManager: Initiating transaction commit  
  18. [08/24 03:39:16] [DEBUG] DataSourceTransactionManager: Committing JDBC transaction on Connection [[email protected]]  
  19. [08/24 03:39:16] [DEBUG] DataSourceTransactionManager: Triggering afterCommit synchronization  
  20. [08/24 03:41:40] [DEBUG] TransactionInterceptor: Completing transaction for [usertest.dao.UsersDAO.testInsertAndUpdate] after exception: usertest.exception.BusinessException: Error  
  21. [08/24 03:41:40] [DEBUG] RuleBasedTransactionAttribute: Applying rules to determine whether transaction should rollback on usertest.exception.BusinessException: Error  
  22. [08/24 03:41:40] [DEBUG] RuleBasedTransactionAttribute: Winning rollback rule is: RollbackRuleAttribute with pattern [Exception]  
  23. [08/24 03:41:40] [DEBUG] DataSourceTransactionManager: Triggering beforeCompletion synchronization  
  24. [08/24 03:41:40] [DEBUG] DataSourceTransactionManager: Initiating transaction rollback  
  25. [08/24 03:41:40] [DEBUG] DataSourceTransactionManager: Rolling back JDBC transaction on Connection [[email protected]]  
  26. [08/24 03:41:40] [DEBUG] DataSourceTransactionManager: Triggering afterCompletion synchronization  
  27. [08/24 03:41:40] [DEBUG] TransactionSynchronizationManager: Clearing transaction synchronization  
[08/24 03:35:39] [DEBUG] RuleBasedTransactionAttribute: Applying rules to determine whether transaction should rollback on usertest.exception.BusinessException: Error
[08/24 03:35:39] [DEBUG] RuleBasedTransactionAttribute: Winning rollback rule is: RollbackRuleAttribute with pattern [BusinessException]
[08/24 03:35:39] [DEBUG] DataSourceTransactionManager: Triggering beforeCompletion synchronization
[08/24 03:35:39] [DEBUG] DataSourceTransactionManager: Initiating transaction rollback
[08/24 03:35:39] [DEBUG] DataSourceTransactionManager: Rolling back JDBC transaction on Connection [[email protected]]
[08/24 03:35:39] [DEBUG] DataSourceTransactionManager: Triggering afterCompletion synchronization
[08/24 03:35:39] [DEBUG] TransactionSynchronizationManager: Clearing transaction synchronization
[08/24 03:35:39] [DEBUG] TransactionSynchronizationManager: Removed value [[email protected]] for key [[email protected]] from thread [main]
[08/24 03:35:39] [DEBUG] DataSourceTransactionManager: Releasing JDBC Connection [[email protected]] after transaction
[08/24 03:35:39] [DEBUG] DataSourceUtils: Returning JDBC Connection to DataSource




[08/24 03:39:16] [DEBUG] TransactionInterceptor: Completing transaction for [usertest.dao.UsersDAO.testInsertAndUpdate] after exception: java.lang.Exception: Error
[08/24 03:39:16] [DEBUG] RuleBasedTransactionAttribute: Applying rules to determine whether transaction should rollback on java.lang.Exception: Error
[08/24 03:39:16] [DEBUG] RuleBasedTransactionAttribute: Winning rollback rule is: null
[08/24 03:39:16] [DEBUG] RuleBasedTransactionAttribute: No relevant rollback rule found: applying superclass default
[08/24 03:39:16] [DEBUG] DataSourceTransactionManager: Triggering beforeCommit synchronization
[08/24 03:39:16] [DEBUG] DataSourceTransactionManager: Triggering beforeCompletion synchronization
[08/24 03:39:16] [DEBUG] DataSourceTransactionManager: Initiating transaction commit
[08/24 03:39:16] [DEBUG] DataSourceTransactionManager: Committing JDBC transaction on Connection [[email protected]]
[08/24 03:39:16] [DEBUG] DataSourceTransactionManager: Triggering afterCommit synchronization


[08/24 03:41:40] [DEBUG] TransactionInterceptor: Completing transaction for [usertest.dao.UsersDAO.testInsertAndUpdate] after exception: usertest.exception.BusinessException: Error
[08/24 03:41:40] [DEBUG] RuleBasedTransactionAttribute: Applying rules to determine whether transaction should rollback on usertest.exception.BusinessException: Error
[08/24 03:41:40] [DEBUG] RuleBasedTransactionAttribute: Winning rollback rule is: RollbackRuleAttribute with pattern [Exception]
[08/24 03:41:40] [DEBUG] DataSourceTransactionManager: Triggering beforeCompletion synchronization
[08/24 03:41:40] [DEBUG] DataSourceTransactionManager: Initiating transaction rollback
[08/24 03:41:40] [DEBUG] DataSourceTransactionManager: Rolling back JDBC transaction on Connection [[email protected]]
[08/24 03:41:40] [DEBUG] DataSourceTransactionManager: Triggering afterCompletion synchronization
[08/24 03:41:40] [DEBUG] TransactionSynchronizationManager: Clearing transaction synchronization

相關推薦

Spring 宣告事務transactionAttributes屬性 +

下面是一段典型的spring 宣告事務的配置: 檢視文字列印? <beanid="userDAOProxy"     class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">   

Spring配置事務transactionAttributes屬性含義及XML配置

                transactionAttributes 屬性:PROPAGATION事務傳播行為型別說明PROPAGATION_REQUIRED如果當前沒有事務,就新建一個事務,如果已經存在一個事務中,加入到這個事務中。這是最常見的選擇。PROPAGATION_SUPPORTS支援當前事務

Spring配置事務@Transactional各個屬性定義

Spring中的@Transactional比較重要的一些屬性,比如 Propagation(事務傳播屬性),Isolation(事務隔離級別),Rollback Rules(事務回滾規則,預設情況是RunTimeException的時候回滾,即unchecked exc

spring宣告事務失效問題(二)

上次談到spring的aop無法攔截內部方法呼叫時,解決方案之一是重新獲取代理類呼叫B方法。 下面說一下如何獲取到代理bean。 1、如果知道beanName直接通過上下文獲取到bean。 2、如果不

Spring 配置檔案 元素 屬性 說明

<beans /> 元素 該元素是根元素。<bean /> 元素的屬性 default-init // 是否開啟懶載入。預設為 false default-dependency-check // 預設為 none default-autowire // 是否自動轉配。預設

spring宣告事務失效問題

問題:      在專案開發中遇到了一個spring事務失效的問題,檢查配置文件,都沒有問題,其他的類中的方法都能進行事務管理,而這個類中的方法卻不行。 分析      檢視程式碼發現三個問題: 原因1、在方法內抓了異常,但是沒有往外拋。注:以前這個是手動事務,後來改成了宣告

spring mvc controller獲取屬性檔案(properties)的值

1.將properties檔案位置加到spring mvc的配置的檔案(spring-mvc.xml)中,如下 <bean id="placeholderConfig" class="org.springframework.beans.facto

Spring-Service-事務執行緒異常執行事務回滾的方式

方式一: 使用Callable, 利用Callable的返回值判斷是否需要進行事務回滾 ExecutorService service = Executors.newCachedThreadP

Spring -12 -宣告事務及完整的XML配置檔案資訊 -宣告事務的相關屬性(tx:advice的標籤)

1.程式設計式事務: 1.1由程式設計師程式設計事務控制程式碼.   1.2OpenSessionInView 就屬於程式設計式事務: session.commit()和rollback() 2.宣告式事務:   2.1事務控制程式碼已經由spring 寫好.程式設計師只需要宣告出哪些方法需

Spring --15.Spring基於xml的宣告事務控制

開發環境: jdk1.8 Idea 2017 :Maven工程、引入父工程 Tomcat:apache-tomcat-8 Spring:5.0.7 一、事務控制 1、概述 事務的概念: 事務是邏輯上一組操作、組成這組操作各個邏輯單元、要麼一起成功、要麼一起失敗。 事

mysql事務管理及spring宣告事務主動異常丟擲使資料庫回滾

原文: http://www.cnblogs.com/wanglonghai/p/4866512.html   mysql的引擎常用的有兩個,一個MyISAM,另一個是InnoDB,mysql預設的為MyISAM,而InnoDB才是支援事務的。所以一般需要修改下

Spring使用屬性文件properties的兩種方式

文件 location 郵件發送 class mave red onf 路徑 文件內容 實際項目中,通常將可配置的參數放到屬性文件中,例如數據庫連接信息、redis連接信息等,便於統一管理。然後通過IoC框架spring將其加載到上下文中,使得程序可以直接使用。 創建mys

假設分配給命令的連接位於本地掛起事務,ExecuteReader 要求命令擁有事務。命令的 Transaction 屬性尚未初始化

execute ati com data- dap system.in tty exceptio ada {System.InvalidOperationException: 假設分配給命令的連接位於本地掛起事務中。ExecuteReader 要求命令擁

關於Spring boot讀取屬性配置文件出現中文亂碼的問題

led Coding uri oot serve http 添加 message 程序 1.再配置文件(application.properties)中添加編碼字符集 #返回頁面、數據中文亂碼問題spring.http.encoding.force=truespring.h

關於Spring boot讀取屬性配置文件出現中文亂碼的問題的解決(針對application.properties)

HA inf encoding 屬性 文件中 ide for 出現 spring 兩種方法: 方法一:在配置文件中設置中文編碼: banner.charset=utf-8server.tomcat.uri-encoding=UTF-8spring.http.encoding

Spring獲取properties文件屬性

https lac 整理 rop spring配置 bar BE adp snippet 1.前言 本文主要是對這兩篇blog的整理,感謝作者的分享 Spring使用程序方式讀取properties文件 Spring通過@Value註解註入屬性的幾種方式 2.配

spring 聲明式事務try catch捕獲異常

調用 color exception 代碼 狀態 新的 for 自定義 這樣的 原文:http://heroliuxun.iteye.com/blog/848122 今天遇到了一個這個問題 最近遇到這樣的問題,使用spring時,在業務層需要捕獲異常(特殊需要),當前一般

數據庫事務的隔離級別和鎖+spring Transactional註解

遇到 丟失更新 讀鎖 討論 acid 通過 行修改 nal dbms 數據庫事務中的隔離級別和鎖 數據庫事務在後端開發中占非常重要的地位,如何確保數據讀取的正確性、安全性也是我們需要研究的問題。 ACID 首先總結一下數據庫事務正確執行的四個要素(ACID): 原子性(At

Spring整合Kafka事務

       原文連結:https://docs.spring.io/spring-kafka/reference/htmlsingle/#transactions 事務Transactions  &nb

spring管理事務屬性事務4種隔離級別 理解事務的4種隔離級別

理解事務的4種隔離級別 資料庫事務的隔離級別有4種,由低到高分別為Read uncommitted 、Read committed 、Repeatable read 、Serializable 。而且,在事務的併發操作中可能會出現髒讀,不可重複讀,幻讀。下面通過事例一一闡述