`
blue2048
  • 浏览: 183327 次
  • 性别: 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-jdbc源码

    《深入剖析Spring-JDBC源码》 Spring-JDBC是Spring框架的一个重要模块,它提供了一种简化数据库操作的抽象层,使得开发者可以更加方便地进行数据访问。在本篇文章中,我们将深入探讨Spring-JdbcTemplate、...

    spring1.2的配置-jdbc

    <bean id="tranManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 业务逻辑层配置 --> <!-- 事务代理配置 --> ...

    spring-jdbc-4.2.4.RELEASE.jar,spring-tx-4.2.4.RELEASE.jar,jdbcTemplate使用的jar包

    总的来说,`spring-jdbc-4.2.4.RELEASE.jar`和`spring-tx-4.2.4.RELEASE.jar`这两个jar包是Spring框架中处理数据库交互和事务管理的核心组件。`jdbcTemplate`作为Spring JDBC的核心工具,极大地简化了数据库访问,而...

    spring-jdbc-4.1.1.RELEASE.zip

    《Spring JDBC 4.1.1.RELEASE:深入解析与应用》 在IT行业中,Spring框架无疑是Java企业级开发中的重要支柱,它以其强大的功能、模块化的架构和丰富的社区支持而备受赞誉。本文将深入探讨Spring JDBC 4.1.1.RELEASE...

    spring-jdbc.rar源码 学习分析用

    在源码中,我们可以看到TransactionManager接口及其实现,如DataSourceTransactionManager,它是Spring对数据库事务进行控制的核心。当开启事务时,Spring会通过保存点或回滚操作确保数据的一致性。通过分析源码,...

    spring jdbc.zip

    3. spring-jdbc-5.1.10.RELEASE.jar:Spring JDBC模块,包含JdbcTemplate和其他数据库相关工具。 4. spring-tx-5.1.10.RELEASE.jar:Spring的事务管理模块,提供事务处理支持。 5. commons-logging-1.2.jar:Apache ...

    spring-jdbc4.0jar包

    这个"spring-jdbc4.0.jar"包是针对Spring框架4.0版本的JDBC支持组件,包含了一系列接口和类,用于简化数据库的访问过程。 首先,Spring JDBC的核心类`JdbcTemplate`是其主要功能的入口点。这个模板类提供了大量的...

    Spring对JDBC的支持jar包.rar

    本压缩包包含"spring-jdbc-4.3.7.RELEASE.jar"和"spring-tx-4.3.7.RELEASE.jar"两个核心组件,它们在Spring框架中扮演着关键角色。 "spring-jdbc-4.3.7.RELEASE.jar"是Spring对JDBC进行抽象和封装的模块,它提供了...

    SpringJDBC注解事务.zip

    本篇文章将深入探讨Spring JDBC如何通过注解来实现事务管理。 1. **Spring JDBC简介** Spring JDBC提供了一个JdbcTemplate类,它封装了常见的JDBC操作,如执行SQL查询、更新、调用存储过程等,减少了代码量和出错...

    Spring Jdbc的jar包

    首先,`spring-jdbc-3.2.0.RELEASE.jar` 包含了Spring JDBC的主要类和接口,如`JdbcTemplate`和`SimpleJdbcInsert`等。`JdbcTemplate`是Spring JDBC的核心,它提供了一种模板方法模式来执行常见的JDBC操作,如查询、...

    Spring集成的jdbc编码和事务管理

    本篇文章将详细讲解Spring如何与JDBC(Java Database Connectivity)集成,实现数据库的编码和事务管理。 首先,Spring提供了一个JdbcTemplate类,它是Spring JDBC模块的核心,用于简化JDBC编程。通过使用...

    spring-tx-5.0.0.0.RELEASE.jar_java开发_spring-tx-5.0.0_

    《深入解析Spring TX 5.0.0:构建高效事务管理》 在Java开发领域,Spring框架以其强大的功能和灵活性而备受青睐。其中,Spring TX模块是Spring框架的重要组成部分,专注于提供事务管理服务。本文将深入探讨Spring ...

    spring事务操作试验

    本文将深入探讨在"spring事务操作试验"中涉及的关键知识点,并结合提供的资源进行详细阐述。 首先,Spring事务管理的核心概念是ACID(原子性、一致性、隔离性和持久性),这是所有事务系统的基础。在Spring中,事务...

    使用Spring的声明式事务----AOP方式

    本文将深入探讨如何利用Spring的声明式事务来处理业务操作中的数据一致性问题,以及相关源码解析。 首先,我们需要了解Spring的AOP概念。AOP是一种编程范式,它允许程序员定义“切面”,这些切面可以包含业务逻辑的...

    spring-boot-starter-mybatis-spring-boot-1.3.4.zip

    Spring Boot默认使用`DataSourceTransactionManager`作为事务管理器,通过`@Transactional`注解可以声明式地控制事务的边界。 7. **性能优化** `spring-boot-starter-mybatis`还提供了缓存支持,可以利用MyBatis...

    使用Spring的声明式事务----Annotation注解方式

    本篇文章将深入探讨如何使用Spring的声明式事务,特别是通过Annotation注解方式进行设置。 首先,我们需要理解什么是声明式事务。与编程式事务(即手动编写事务管理代码)不同,声明式事务是通过AOP(面向切面编程...

    Spring事务处理-ThreadLocal的使用

    Spring事务处理是其核心特性之一,确保了数据的一致性和完整性。本篇文章将聚焦于Spring事务处理中ThreadLocal的使用,以及如何通过源码理解和应用这个工具。 首先,了解Spring事务管理的基本概念。在多线程环境中...

    spring JDBC事务管理

    **源码分析**:深入理解Spring JDBC事务管理的源码,可以帮助开发者更好地定制和优化事务处理。关键类如`TransactionDefinition`定义了事务属性,如隔离级别、超时时间等;`TransactionStatus`接口则表示当前事务的...

    spring学习之八--Hibernate编程式事务

    而PlatformTransactionManager接口是Spring事务管理的抽象,提供了开始、提交、回滚事务的方法,例如DataSourceTransactionManager(适用于JDBC)和HibernateTransactionManager(适用于Hibernate)。 以下是一个...

    Spring-Boot-JDBC-MySQL:Spring Boot + JDBC + MySQL

    在本项目"Spring-Boot-JDBC-MySQL"中,我们将探讨如何使用Spring Boot框架与JDBC(Java Database Connectivity)一起工作,以实现与MySQL数据库的交互。Spring Boot简化了传统Spring应用的初始设置,提供了自动配置...

Global site tag (gtag.js) - Google Analytics