`
blue2048
  • 浏览: 178242 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

spring事务深入剖析 - JDBC DataSourceTransactionManager 分析

阅读更多

首先介绍下DataSourceTransactionObject这个类,它是DataSourceTransactionManager的事务句柄,用于和AbstractPlatformTransactionManager接口方法之间的交互数据传递

 下面介绍DataSourceTransactionManager各个方法,解析见注释

1.  doGetTransaction

//产生一个DataSourceTransactionObject对象,其中持有ConnectionHolder(从ThreadLocale中拿,可能已经存在这个对象)
protected Object doGetTransaction() {
		DataSourceTransactionObject txObject = new DataSourceTransactionObject();
		txObject.setSavepointAllowed(isNestedTransactionAllowed());
		ConnectionHolder conHolder =
			(ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
		txObject.setConnectionHolder(conHolder, false);
		return txObject;
	}

 

 

2. isExistingTransaction

 

//从DataSourceTransactionObject取出ConnectionHolder对象,判断connection上是否已经开启过事务protected boolean isExistingTransaction(Object transaction) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
		return (txObject.getConnectionHolder() != null && txObject.getConnectionHolder().isTransactionActive());
	}

 

3. doBegin

    a. 从DataSourceTransactionObject拿出ConnectionHolder

    b. 从ConnectionHolder拿Connection,设置事务的隔离级别,并开启事务

    c. 将ConnectionHolder绑定到当前Connection上,以被嵌套的事务获取(因为JDBC连接池是根据线程绑定Connection的,所有一次嵌套事务中,使用的是同一个Connection)

protected void doBegin(Object transaction, TransactionDefinition definition) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
		Connection con = null;

		try {
			if (txObject.getConnectionHolder() == null ||
					txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
				Connection newCon = this.dataSource.getConnection();
				if (logger.isDebugEnabled()) {
					logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
				}
				txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
			}

			txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
			con = txObject.getConnectionHolder().getConnection();

			Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
			txObject.setPreviousIsolationLevel(previousIsolationLevel);

			// Switch to manual commit if necessary. This is very expensive in some JDBC drivers,
			// so we don't want to do it unnecessarily (for example if we've explicitly
			// configured the connection pool to set it already).
			if (con.getAutoCommit()) {
				txObject.setMustRestoreAutoCommit(true);
				if (logger.isDebugEnabled()) {
					logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
				}
				con.setAutoCommit(false);
			}
			txObject.getConnectionHolder().setTransactionActive(true);

			int timeout = determineTimeout(definition);
			if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
				txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
			}

			// Bind the session holder to the thread.
			if (txObject.isNewConnectionHolder()) {
				TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());
			}
		}

		catch (Exception ex) {
			DataSourceUtils.releaseConnection(con, this.dataSource);
			throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
		}
	}

 

 

4. doSuspend 

 

//清除DataSourceTransactionObject和ThreadLocal中存储的ConnectionHolder对象,外部保存ConnectionHolder对象,以备恢复使用
protected Object doSuspend(Object transaction) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
		txObject.setConnectionHolder(null);
		ConnectionHolder conHolder = (ConnectionHolder)
				TransactionSynchronizationManager.unbindResource(this.dataSource);
		return conHolder;
	}
 
5. doResume
//外部传入ConnectionHolder对象,恢复到ThreadLocal中去	
protected void doResume(Object transaction, Object suspendedResources) {
		ConnectionHolder conHolder = (ConnectionHolder) suspendedResources;
		TransactionSynchronizationManager.bindResource(this.dataSource, conHolder);
	}
 
6. doCommit
protected void doCommit(DefaultTransactionStatus status) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
		Connection con = txObject.getConnectionHolder().getConnection();
		if (status.isDebug()) {
			logger.debug("Committing JDBC transaction on Connection [" + con + "]");
		}
		try {
			con.commit();
		}
		catch (SQLException ex) {
			throw new TransactionSystemException("Could not commit JDBC transaction", ex);
		}
	}
 
7. doRollback
protected void doRollback(DefaultTransactionStatus status) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
		Connection con = txObject.getConnectionHolder().getConnection();
		if (status.isDebug()) {
			logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");
		}
		try {
			con.rollback();
		}
		catch (SQLException ex) {
			throw new TransactionSystemException("Could not roll back JDBC transaction", ex);
		}
	}
 
8. doSetRollbackOnly
protected void doSetRollbackOnly(DefaultTransactionStatus status) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
		if (status.isDebug()) {
			logger.debug("Setting JDBC transaction [" + txObject.getConnectionHolder().getConnection() +
					"] rollback-only");
		}
		txObject.setRollbackOnly();
	}
 
9. doCleanupAfterCompletion
    a. 从ThreadLocal中将ConnectionHolder清除
    b. 回复Connecton之前的AutoCommit和IsolationLevel属性
    c. 释放connection
    d. 清除ConnectHolder相应的对象属性
protected void doCleanupAfterCompletion(Object transaction) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;

		// Remove the connection holder from the thread, if exposed.
		if (txObject.isNewConnectionHolder()) {
			TransactionSynchronizationManager.unbindResource(this.dataSource);
		}

		// Reset connection.
		Connection con = txObject.getConnectionHolder().getConnection();
		try {
			if (txObject.isMustRestoreAutoCommit()) {
				con.setAutoCommit(true);
			}
			DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel());
		}
		catch (Throwable ex) {
			logger.debug("Could not reset JDBC Connection after transaction", ex);
		}

		if (txObject.isNewConnectionHolder()) {
			if (logger.isDebugEnabled()) {
				logger.debug("Releasing JDBC Connection [" + con + "] after transaction");
			}
			DataSourceUtils.releaseConnection(con, this.dataSource);
		}

		txObject.getConnectionHolder().clear();
	}
 
分享到:
评论

相关推荐

    spring-boot-jdbc-hiraki:Proyecto Spring Boot扩展了Conexiones和JDBC

    Proyecto Spring Boot Condeiones和JDBC的示例Elementos Utilziados HirakiConfig 数据源NamedParameterJdbcTemplate DataSourceTransactionManager LombokSqlParameterSource BeanPropertySqlParameterSource ...

    springboot-jdbc-aop-transactional-demo:源码主要用于学习Spring事务,内容包括通过AOP机制加注解(Annotation)方式实现事务,事务源为JDBC数据源下的DataSourceTransactionManager,并合并Swagger-UI-2.9.2进行调试,数据库采用MySQL,持久层使用JDBC

    springboot-jdbc-aop-transactional-demo

    jdbc——内嵌事务

    class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> <property name="dataSource" ref="dataSource"></property> ...

    spring-framework-reference-4.1.2

    3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................

    Spring-Reference_zh_CN(Spring中文参考手册)

    9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. <tx:advice/> 有关的设置 9.5.6. 使用 @Transactional 9.5.6.1. @Transactional 有关的设置 ...

    spring applicationContext 配置文件

    <bean id="transactionManagerPdm" class="org.springframework.jdbc.datasource.DataSourceTransactionManager " p:dataSource-ref="dataSourcePdm"/> <!-- 配置事务的传播特性 --> ...

    springmvc-ibatis

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- Spring AOP config配置切点 --> (* com.org.service.*.*(..))" id=...

    Maven拆分代码.zip

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!--配置事务的通知--> *" propagation="REQUIRED"/> *" propagation="REQUIRED"/> *" ...

    Spring MVC 入门实例

    16 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 17 18 19 --> 20 21 <!-- 22 23 24 25 --> 26 27 它配置了以下功能(不过,已经注释掉了): ...

    深入解析Spring核心API: 打造高效Java应用

    除此之外,文档还深入介绍了Spring的事务管理能力,特别是DataSourceTransactionManager,它为数据库操作提供了一致的事务管理接口。这些特性使得Spring在处理复杂的企业级应用时更加高效和可靠。 通过对这些核心API...

    注入JdbcTemplate启用事务管理.docx

    1、引入spring的jdbc、数据库驱动,数据源 2、配置数据源,注入JdbcTemplate,启用事务管理,注入DataSourceTransactionManager 3、传播机制 @see Propagation#REQUIRED 支持当前事务,如果没有则新建一个事务, 例:...

    spring chm文档

    9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. <tx:advice/> 有关的设置 9.5.6. 使用 @Transactional 9.5.7. 插入事务操作 9.5.8. ...

    spring-framework-reference4.1.4

    3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................

    Spring.html

    Mybatis/jdbc:DataSourceTransactionManager Hibernater:HibernaterTransactionManager TransactionManagerDifinition 传播行为:A-->B,在B上声明是否一定需要事务管理 requerd:必须的(默认),如果A有事务...

    Spring3中配置DBCP,C3P0,Proxool,Bonecp数据源

    class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> ...

    Spring 2.0 开发参考手册

    9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. <tx:advice/> 有关的设置 9.5.6. 使用 @Transactional 9.5.7. 插入事务操作 9.5.8. ...

    Spring中文帮助文档

    9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. <tx:advice/> 有关的设置 9.5.6. 使用 @Transactional 9.5.7. 事务传播 9.5.8. 通知...

    Spring API

    9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. <tx:advice/> 有关的设置 9.5.6. 使用 @Transactional 9.5.7. 事务传播 9.5.8. 通知...

    springmvcmybatis

    class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 配置事务通知属性 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 定义事务传播...

Global site tag (gtag.js) - Google Analytics