1. 程式人生 > >【Spring實戰】----Spring事務管理配置解析

【Spring實戰】----Spring事務管理配置解析

上篇說了aop的配置,並且說了Spring事務管理是基於aop的,那麼Spring宣告式事務的配置就有兩種方式:XML配置及註解配置

不多說,直接看配置檔案

一、配置檔案

applicationContext-transaction.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	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.xsd
		http://www.springframework.org/schema/aop 
		http://www.springframework.org/schema/aop/spring-aop.xsd 
		http://www.springframework.org/schema/tx 
		http://www.springframework.org/schema/tx/spring-tx.xsd ">
		
	<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
	
	<!-- 通知 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<!-- 傳播行為 -->
			<tx:method name="save*" propagation="REQUIRED"/>
			<tx:method name="delete*" propagation="REQUIRED"/>
			<tx:method name="insert*" propagation="REQUIRED"/>
			<tx:method name="update*" propagation="REQUIRED"/>
			<tx:method name="list*" propagation="SUPPORTS" read-only="true"/>
			<tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
		</tx:attributes>
	</tx:advice>
	
	<!-- aop -->
	<aop:config>
		<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.mango.jtt.service.*.*(..))"/>
	</aop:config>

	<!-- 註解管理事務 -->
	<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

註解管理事務以上都是xml配置的事務,基於註解的事務,只需配置<tx:annotation-driven/>標籤,然後在Spring bean中新增@Transational註解即可實現事務管理。

二,Spring事務管理本質

Spring並不直接管理事務,而是提供多種事務管理器,他們講事務管理的職責委託給JAT或其他持久化機制所提供的平臺相關的事務實現。上述配置檔案中就是利用的Hibernate事務管理器實現的Hibernate事務管理。詳細資訊不說,想事務屬性什麼的,具體可參考spring in action及spring官方文件

三、繼續說下事務對getCurrentSession的影響

首先看事務管理器HibernateTransactionManager,它並沒有做太多工作,一個空的建構函式及

/**
	 * Create a new HibernateTransactionManager instance.
	 * A SessionFactory has to be set to be able to use it.
	 * @see #setSessionFactory
	 */
	public HibernateTransactionManager() {
	}

及afterPropertiesSet()方法

@Override
	public void afterPropertiesSet() {
		if (getSessionFactory() == null) {
			throw new IllegalArgumentException("Property 'sessionFactory' is required");
		}
		if (this.entityInterceptor instanceof String && this.beanFactory == null) {
			throw new IllegalArgumentException("Property 'beanFactory' is required for 'entityInterceptorBeanName'");
		}

		// Check for SessionFactory's DataSource.
		if (this.autodetectDataSource && getDataSource() == null) {
			DataSource sfds = SessionFactoryUtils.getDataSource(getSessionFactory());
			if (sfds != null) {
				// Use the SessionFactory's DataSource for exposing transactions to JDBC code.
				if (logger.isInfoEnabled()) {
					logger.info("Using DataSource [" + sfds +
							"] of Hibernate SessionFactory for HibernateTransactionManager");
				}
				setDataSource(sfds);
			}
		}
	}


可見事務管理器的初始化並沒有做太多工作。那麼看事務管理對其的影響,先看呼叫棧

TransactionSynchronizationManager.initSynchronization() line: 269	
HibernateTransactionManager(AbstractPlatformTransactionManager).prepareSynchronization(DefaultTransactionStatus, TransactionDefinition) line: 542	
HibernateTransactionManager(AbstractPlatformTransactionManager).prepareTransactionStatus(TransactionDefinition, Object, boolean, boolean, boolean, Object) line: 513	
HibernateTransactionManager(AbstractPlatformTransactionManager).getTransaction(TransactionDefinition) line: 393	
TransactionInterceptor(TransactionAspectSupport).createTransactionIfNecessary(PlatformTransactionManager, TransactionAttribute, String) line: 426	
TransactionInterceptor(TransactionAspectSupport).invokeWithinTransaction(Method, Class<?>, InvocationCallback) line: 275	
TransactionInterceptor.invoke(MethodInvocation) line: 96	
ReflectiveMethodInvocation.proceed() line: 179	
ExposeInvocationInterceptor.invoke(MethodInvocation) line: 92	
ReflectiveMethodInvocation.proceed() line: 179	
JdkDynamicAopProxy.invoke(Object, Method, Object[]) line: 213	
$Proxy316.getOrderById(String) line: not available	
OrderController.orderPay(String, Model) line: 84	

從呼叫棧可以看出,只要在連線點處配置了事務管理,首先都會走到initSynchronization()。

/**
	 * Activate transaction synchronization for the current thread.
	 * Called by a transaction manager on transaction begin.
	 * @throws IllegalStateException if synchronization is already active
	 */
	public static void initSynchronization() throws IllegalStateException {
		if (isSynchronizationActive()) {
			throw new IllegalStateException("Cannot activate transaction synchronization - already active");
		}
		logger.trace("Initializing transaction synchronization");
		synchronizations.set(new LinkedHashSet<TransactionSynchronization>());
	}

最終會在synchronizations中set進new LinkedHashSet<TransactionSynchronization>(),從而isSynchronizationActive()為true
/**
	 * Return if transaction synchronization is active for the current thread.
	 * Can be called before register to avoid unnecessary instance creation.
	 * @see #registerSynchronization
	 */
	public static boolean isSynchronizationActive() {
		return (synchronizations.get() != null);
	}


因此這裡也就解釋了上上篇留下的疑問,為什麼配置了事務管理,就不會拋異常了。其實只有配置了事務,session就會在事務提交或者回滾後關閉

SessionImpl.close() line: 402	
SessionFactoryUtils.closeSession(Session) line: 167	
SpringSessionSynchronization.afterCompletion(int) line: 138	
TransactionSynchronizationUtils.invokeAfterCompletion(List<TransactionSynchronization>, int) line: 168	
HibernateTransactionManager(AbstractPlatformTransactionManager).invokeAfterCompletion(List<TransactionSynchronization>, int) line: 1001	
HibernateTransactionManager(AbstractPlatformTransactionManager).triggerAfterCompletion(DefaultTransactionStatus, int) line: 976	
HibernateTransactionManager(AbstractPlatformTransactionManager).processCommit(DefaultTransactionStatus) line: 806	
HibernateTransactionManager(AbstractPlatformTransactionManager).commit(TransactionStatus) line: 730	
TransactionInterceptor(TransactionAspectSupport).commitTransactionAfterReturning(TransactionAspectSupport$TransactionInfo) line: 483	
TransactionInterceptor(TransactionAspectSupport).invokeWithinTransaction(Method, Class<?>, InvocationCallback) line: 290	
TransactionInterceptor.invoke(MethodInvocation) line: 96	
ReflectiveMethodInvocation.proceed() line: 179	
ExposeInvocationInterceptor.invoke(MethodInvocation) line: 92	
ReflectiveMethodInvocation.proceed() line: 179	
JdkDynamicAopProxy.invoke(Object, Method, Object[]) line: 213	
$Proxy316.getOrderById(String) line: not available	
OrderController.orderPayInfo(String, Model) line: 72	




相關推薦

Spring實戰----Spring事務管理配置解析

上篇說了aop的配置,並且說了Spring事務管理是基於aop的,那麼Spring宣告式事務的配置就有兩種方式:XML配置及註解配置不多說,直接看配置檔案一、配置檔案applicationContext-transaction.xml<?xml version="1.0

Spring實戰----spring security4.1.3配置以及踩過的坑

一、所需的庫檔案//spring-security compile 'org.springframework.security:spring-security-web:4.1.3.RELEASE' compile 'org.springframework.security

Spring實戰Spring註解配置工作原理原始碼解析

一、背景知識在【Spring實戰】Spring容器初始化完成後執行初始化資料方法一文中說要分析其實現原理,於是就從原始碼中尋找答案,看原始碼容易跑偏,因此應當有個主線,或者帶著問題、目標去看,這樣才能最大限度的提升自身程式碼水平。由於上文中大部分都基於註解進行設定的(Spri

Spring實戰----Spring配置檔案的解析

一、背景知識Spring的核心的核心就是bean的配置及管理,至Spring最新發布的版本4.3.2已經有三種方式可以配置bean:1)在XML中進行顯示配置2)在Java中進行顯示配置3)隱式的bean發現機制和自動裝配上述三種配置不展開說明,而且目前用的較多的是第3種(當

Maven實戰之版本管理

前言 版本管理:指專案整體版本的演變過程管理。 版本控制:指藉助版本控制工具追蹤程式碼的每一個變更。 何為版本管理 對內專案開發,應該使用快照版本 對外發布時,應該提供非常穩定的版本。

SpringJDBC事務管理XML配置

將spring事務管理與spirng-mybatis分離開了: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/bean

Spring實戰----原始碼解析SessionFactory及Session的管理及getCurrentSession的使用

在上一篇Hibernate5整合中當使用sessionFactory.getCurrentSession()時會報錯Could not obtain transaction-synchronized Session for current thread,本篇就從原始碼角度

Spring實戰----springMVC4.3.2的配置

一、簡單說明 本篇springMVC的配置涉及到springMVC配置、sitemesh配置、log4j2的配置 二、相關庫檔案 根據myeclipse中建立gradle web專案建立完成後(建議使用idea進行,本系列也已用idea進行分析),在

2016-08-15{全面分析 Spring 的程式設計式事務管理及宣告式事務管理}

       與前面相似,transaction-manager 屬性的預設值是 transactionManager,如果事務管理器 Bean 的名字即為該值,則可以省略該屬性。        雖然 @Transactional 註解可以作用於介面、介面方法、類以及類方法上,但是 Spring

spring,mybatis事務管理配置與@Transactional註解使用[轉]

exception true throws r.java 存在 隔離 enc prot 底層 spring,mybatis事務管理配置與@Transactional註解使用 概述事務管理對於企業應用來說是至關重要的,即使出現異常情況,它也可以保證數據的一致性。Sprin

日常錯誤spring-boot配置文件讀取不到

無法 pan factory sdn 一個 pre nco span xxx 最近在用spring-boot做項目時,遇到自定義的配置文件無法讀取到的問題,通過在appcation.java類上定義@PropertySource(value = {"classpath:XX

spring,mybatis事務管理配置與@Transactional註解使用

抽象 classname 初始 for batis 時間限制 自動提交 data second spring,mybatis事務管理配置與@Transactional註解使用 概述事務管理對於企業應用來說是至關重要的,即使出現異常情況,它也可以保證數據的一致性。Spring

Spring Security七、RememberMe配置

rop 基於 fig mep alias tom 保存 統一 source 一、概述 RememberMe 是指用戶在網站上能夠在 Session 之間記住登錄用戶的身份的憑證,通俗的來說就是用戶登陸成功認證一次之後在制定的一定時間內可以不用再輸入用戶名和密碼進行自動登錄

spring 事務管理配置

本篇文章只涉及spring事務的配置,不進行事務的介紹。 spring通過PlatformTransactionManager介面作為事務管理器來進行事務的管理,它本身並不進行事務的建立以及相關操作,它就相當於事務管理的容器,裡面放的是事務。事務使用有程式設計式事務和宣告式事務,現在一般情況下都是使用宣告式事

備忘spring boot 和netty 實現聊天工具 從開發到部署實戰

一: 課程概要 二: netty初識及BIO、NIO、AIO等執行緒模型 三: netty編寫簡單伺服器及channel詳解 四: netty與hbuilder開發websocket伺服器 五: H5與MUI構建移動端app 六: 資料庫設計及整合Springboot MyB

Spring事務管理配置及異常詳解

最近在生產專案上出現一些問題,同一流程下涉及到多個數據庫表的增改出現不一致的情況; 例如tableA,tableB,tableC: 三張表同時做insert操作(或者是update操作),其中tableA,tableB儲存成功,tableC卻未能儲存成功;這樣的話,就造成生產伺服器上的資料不準確

複習之spring基礎(三)——Spring事務管理配置AOP事務(XML和註解方式)

事務 事務邏輯上的一組操作,組成這組操作的各個邏輯單元,要麼一起成功,要麼一起失敗 事務的特性 原子性 :強調事務的不可分割. 一致性 :事務的執行的前後資料的完整性保持一致. 隔離性 :一個事務執行的過程中,不應該受到其他事務的干擾. 永續性 :事務一旦結束

Spring Boot中的事務管理實戰

一 什麼是事務 在開發企業應用時,對於業務人員的一個操作實際是對資料讀寫的多步操作的結合。由於資料操作在順序執行的過程中,任何一步操作都有可能發生異常,異常會導致後續操作無法完成,此時由於業務邏輯並未正確的完成,之前成功操作資料的並不可靠,需要在這種情況下進行回退。 事務

備忘Spring Boot從前端到後臺打造企業級部落格全棧實戰視訊

第1章 Spring Boot 簡介    第2章 開啟 Spring Boot 的第一個 Web 專案    第3章 一個Hello World專案    第4章 開發環境的搭建    第5章 整合Thymeleaf模版引擎    第6章 資料持久化Spring Data

spring-bootspring-boot-配置嵌入式Servlet容器學習

8、配置嵌入式Servlet容器SpringBoot預設使用Tomcat作為嵌入式的Servlet容器;問題?1)、如何定製和修改Servlet容器的相關配置;1、修改和server有關的配置(ServerProperties【也是EmbeddedServletContain