`
dylan0514sina.cn
  • 浏览: 94959 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

DataSourceUtils 管理参与事务性的JDBC连接

 
阅读更多
提供一些静态方法用于管理可能参与事务的JDBC连接。JDBCTemplate
或JDBCDaoSupport自动使用它,而且在DataSourceTransactionManager或JTATransactionManager,hibernateTransactionManager中支持。
DataSourceTransactionManager中
  DataSourceTransactionManager.DataSourceTransactionObject在事务开始时存储连接,事务完结后使用它获取连接以回复只读,隔离级别及释放连接。在事务挂起和回复时只是解除或重新绑定Holder到当前线程。
   成员变量
   newConnectionHolder:ConnectionHolder是否为DataSourceTransactionManager doBegin创建。true说明由事务管理器创建,那么在doBegin方法中获取连接并将Holder绑定到线程,在事务完结后由doCleanupAfterCompletion方法接触Holder绑定并释放连接。
   mustRestoreAutoCommit:在事务开始时保存连接自动提交模式,进入Spring事务管理将禁用连接自动提交模式,当事务完结后doCleanupAfterCompletion将回复Spring管理之前连接的自动提交模式(无论是禁用的还是启用的:虽然很多数据源提供了自动连接模式,但Spring要求必须禁用)。
   方法
   hasTransaction  由connectionHolder.isTransactionActive决定,事务开始时设置,完结后清除
   setRollbackOnly 设置本地只读标志,AbstractPlatformTransactionManager中提到

/**
	 * DataSource transaction object, representing a ConnectionHolder.
	 * Used as transaction object by DataSourceTransactionManager.
	 */
	private static class DataSourceTransactionObject extends JdbcTransactionObjectSupport {

		private boolean newConnectionHolder;

		private boolean mustRestoreAutoCommit;

		public void setConnectionHolder(ConnectionHolder connectionHolder, boolean newConnectionHolder) {
			super.setConnectionHolder(connectionHolder);
			this.newConnectionHolder = newConnectionHolder;
		}

		public boolean isNewConnectionHolder() {
			return this.newConnectionHolder;
		}

		public boolean hasTransaction() {
			return (getConnectionHolder() != null && getConnectionHolder().isTransactionActive());
		}

		public void setMustRestoreAutoCommit(boolean mustRestoreAutoCommit) {
			this.mustRestoreAutoCommit = mustRestoreAutoCommit;
		}

		public boolean isMustRestoreAutoCommit() {
			return this.mustRestoreAutoCommit;
		}

		public void setRollbackOnly() {
			getConnectionHolder().setRollbackOnly();
		}

		public boolean isRollbackOnly() {
			return getConnectionHolder().isRollbackOnly();
		}
	} 
   


  DataSourceUtils.ConnectionSynchronization主要用于JTATransactionManager的资源挂起,回复,资源清理;也支持其它应用的资源清理操作。
  方法
  suspend 事务挂起时调用,除了解绑资源更重要的是尽可能早的释放连接,DataSourceUtils可重新获取新的连接并绑定到Holder
  beforeCompletion 事务提交或回滚之前调用,解绑资源和尽可能早的释放连接,当连接被其他应用释放掉DataSourceUtils.releaseConnection(JTA规范规定事务处理完成后,必须关闭所有资源)
  afterCompletion  事务提交或回滚之后调用,在JTATransactionManager支持下,对于参与性事务该方法被注册到J2EE事务管理器上由JTA事务完成后执行,有可能与在一个不同于当前线程的线程中执行,那Holder便不可解除。所以我们必须将连接置空。而且在事务完成之后将事务状态:同步只读事务超时引用全部清空。
   
    
/**
	 * Callback for resource cleanup at the end of a non-native JDBC transaction
	 * (e.g. when participating in a JtaTransactionManager transaction).
	 * @see org.springframework.transaction.jta.JtaTransactionManager
	 */
	private static class ConnectionSynchronization extends TransactionSynchronizationAdapter {

		private final ConnectionHolder connectionHolder;

		private final DataSource dataSource;

		private int order;

		private boolean holderActive = true;

		public ConnectionSynchronization(ConnectionHolder connectionHolder, DataSource dataSource) {
			this.connectionHolder = connectionHolder;
			this.dataSource = dataSource;
			this.order = getConnectionSynchronizationOrder(dataSource);
		}

		@Override
		public int getOrder() {
			return this.order;
		}

		@Override
		public void suspend() {
			if (this.holderActive) {
				TransactionSynchronizationManager.unbindResource(this.dataSource);
				if (this.connectionHolder.hasConnection() && !this.connectionHolder.isOpen()) {
					// Release Connection on suspend if the application doesn't keep
					// a handle to it anymore. We will fetch a fresh Connection if the
					// application accesses the ConnectionHolder again after resume,
					// assuming that it will participate in the same transaction.
					releaseConnection(this.connectionHolder.getConnection(), this.dataSource);
					this.connectionHolder.setConnection(null);
				}
			}
		}

		@Override
		public void resume() {
			if (this.holderActive) {
				TransactionSynchronizationManager.bindResource(this.dataSource, this.connectionHolder);
			}
		}

		@Override
		public void beforeCompletion() {
			// Release Connection early if the holder is not open anymore
			// (that is, not used by another resource like a Hibernate Session
			// that has its own cleanup via transaction synchronization),
			// to avoid issues with strict JTA implementations that expect
			// the close call before transaction completion.
			if (!this.connectionHolder.isOpen()) {
				TransactionSynchronizationManager.unbindResource(this.dataSource);
				this.holderActive = false;
				if (this.connectionHolder.hasConnection()) {
					releaseConnection(this.connectionHolder.getConnection(), this.dataSource);
				}
			}
		}

		@Override
		public void afterCompletion(int status) {
			// If we haven't closed the Connection in beforeCompletion,
			// close it now. The holder might have been used for other
			// cleanup in the meantime, for example by a Hibernate Session.
			if (this.holderActive) {
				// The thread-bound ConnectionHolder might not be available anymore,
				// since afterCompletion might get called from a different thread.
				TransactionSynchronizationManager.unbindResourceIfPossible(this.dataSource);
				this.holderActive = false;
				if (this.connectionHolder.hasConnection()) {
					releaseConnection(this.connectionHolder.getConnection(), this.dataSource);
					// Reset the ConnectionHolder: It might remain bound to the thread.
					this.connectionHolder.setConnection(null);
				}
			}
			this.connectionHolder.reset();
		}
	}


  JTATransactionManager支持下无论事务开始,挂起,回复,完成都与资源操作无关(这是JTA事务具备而本地事务不具备的优点)。在应用中可调用JdbcTemplate或JDBCDaoSupport或DataSourceUtils。在Spring同步激活下,初次调用DataSourceUtils.getConnection时,会注册DataSourceUtils.ConnectionSynchronization实例。hibernateTransactionManager支持下当检测到javax.sql.DataSource时会绑定新的ConnectionHolder,它的connection是由Session提供的因此他只是一个连接代理,没有权利也不必关心连接的释放。只有刚获取的连接才有资格由ConnectionSynchronization资源释放。其它应用与之类似。
 
  方法
  doGetConnection获取JDBC连接
public static Connection doGetConnection(DataSource dataSource) throws SQLException {
		Assert.notNull(dataSource, "No DataSource specified");

		ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
		if (conHolder != null && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) {
//如果Holder被绑定着,并且能使用连接或者Holder作为事务管理器开启事务或Spring同步所管理,这种情况可视为连接可重新获取。
			conHolder.requested();
			if (!conHolder.hasConnection()) {
				logger.debug("Fetching resumed JDBC Connection from DataSource");
				conHolder.setConnection(dataSource.getConnection());
			}
			return conHolder.getConnection();
		}
		// Else we either got no holder or an empty thread-bound holder here.

		logger.debug("Fetching JDBC Connection from DataSource");
                 //获取新的连接
		Connection con = dataSource.getConnection();
                //spring同步激活了,可用同步实例管理资源
		if (TransactionSynchronizationManager.isSynchronizationActive()) {
			logger.debug("Registering transaction synchronization for JDBC Connection");
			// Use same Connection for further JDBC actions within the transaction.
			// Thread-bound object will get removed by synchronization at transaction completion.
			ConnectionHolder holderToUse = conHolder;
			if (holderToUse == null) {
				holderToUse = new ConnectionHolder(con);
			}
			else {
				holderToUse.setConnection(con);
			}
			holderToUse.requested();
			TransactionSynchronizationManager.registerSynchronization(
					new ConnectionSynchronization(holderToUse, dataSource));
			holderToUse.setSynchronizedWithTransaction(true);
			if (holderToUse != conHolder) {
				TransactionSynchronizationManager.bindResource(dataSource, holderToUse);
			}
		}

		return con;
	}
分享到:
评论

相关推荐

    spring-jdbc jar包.rar

    5. **DataSourceUtils** 和 **ConnectionUtils**:这些工具类帮助管理DataSource和数据库连接,确保资源的正确获取和释放,防止资源泄露。 在实际应用中,Spring JDBC提供了以下优势: - **代码简洁性**:通过模板...

    spring连接数据库aop-jdbc

    在"spring连接数据库aop-jdbc"这个主题中,我们主要关注Spring框架如何通过AOP(面向切面编程)和JDBC(Java Database Connectivity)来实现数据库的高效管理。以下是关于这一主题的详细知识: 1. **Spring JDBC...

    spring对jdbc的支持jar包

    6. **DataSourceUtils** 和 **JdbcUtils**:这两个工具类提供了数据库连接池的管理和通用的JDBC辅助方法,如关闭资源,从而帮助开发者编写更健壮的代码。 在实际使用中,Spring JDBC通常与Spring的其他模块结合,如...

    jdbc驱动包

    总结起来,"jdbc驱动包"主要涉及Java的JDBC接口及其驱动程序,而C3p0和DBUtils是两个实用的数据库连接池和数据库操作工具,它们能够帮助开发者更有效地管理和使用数据库连接,提高应用的性能和稳定性。

    spring封装jdbc查询

    4. **事务管理**:Spring JDBC还提供了事务管理能力,可以方便地控制事务的边界,避免在手动管理事务时出现的资源泄露问题。例如,通过`TransactionTemplate`或在配置文件中声明@Transactional注解,可以在方法级别...

    spring.jdbc-3.0.5.jar

    Spring JDBC的主要目标是简化传统的JDBC编程模型,通过提供模板类和数据访问对象(DAO)支持,来处理数据库操作的繁琐过程,如连接管理、事务处理和异常转换等。这一版本3.0.5的发布,进一步优化了性能和稳定性。 ...

    java spring jdbc 常用jar包集合.zip

    - `commons-dbcp.jar` 或 `hikaricp.jar`:这些是连接池库,用于高效管理数据库连接,提高性能和稳定性。 4. **AspectJ相关JARs**: - `aspectjrt.jar` 和 `aspectjweaver.jar`:如果使用AOP(面向切面编程)进行...

    mysql-jdbc-Spring源代码分析

    - **深入了解Spring框架的事务管理机制**:了解如何利用Spring的事务管理特性来增强数据库操作的健壮性和一致性。 - **学习其他Spring提供的DAO支持工具**:除了`JdbcTemplate`外,Spring还提供了针对不同ORM框架的...

    spring基础包+jdbc包+Aspect J.zip

    它包括DataSourceUtils、JdbcTemplate和SimpleJdbcInsert等工具类,帮助开发者以更加安全、便捷的方式执行SQL语句,处理结果集,并管理数据库连接。 3. AspectJ:AspectJ是Java平台上的一个开源项目,提供强大的...

    Spring源代码解析3:SpringJDBC[归纳].pdf

    `DataSource`是Java的JDBC数据源,负责管理数据库连接。在获取到连接后,`JdbcTemplate`可能需要对连接进行特殊处理,如使用`nativeJdbcExtractor`获取原生的数据库连接,或者创建一个关闭抑制的连接代理,以准备...

    Spring jdbc中数据库操作对象化模型的实例详解

    通过DataSource和相关的模板类,Spring JDBC简化了连接管理、事务处理和异常处理,提高了代码的可读性和可维护性。这些工具和设计模式使得在Java应用中使用Spring框架进行数据库操作变得更加高效和方便。

    Spring5源码之JDBC

    4、事务管理在Spring中,JDBC操作通常会参与到事务管理中。当使用JdbcTemplate时,如果在同一个事务上下文中,多个数据库操作会被一起提交或回滚。例如,如果在一个Service方法中连续调用了save和update,它们会被...

    spring事务支持

    总结来说,Spring的事务支持提供了一致的编程模型,简化了事务管理的复杂性,同时通过声明式事务管理使得事务配置更加灵活和易于维护。无论是对于JDBC、Hibernate还是其他持久化技术,Spring都能提供合适的事务管理...

    DButils.zip

    4. **事务管理**:DButils支持手动和自动的事务管理,可以在执行多条SQL语句时保持事务的完整性。 5. **异常处理**:它对JDBC的异常进行了封装,提供了RunTimeException,简化了异常处理流程,使代码更加简洁。 6....

    springframework-1.0.zip早期版本雏形

    总的来说,"springframework-1.0.zip"这个早期版本展示了Spring框架的基本构架和核心特性,包括IoC容器、AOP、MVC、事务管理和JDBC抽象。对于想要深入了解Spring框架历史、设计原理以及其演进过程的程序员来说,这是...

    Spring1.2api参考手册.zip

    DataSourceUtils和JdbcTemplate是其中的关键工具,它们帮助处理连接池管理和SQL执行。 8. **DAO支持**:Spring为数据访问对象(DAO)提供了基类和异常层次结构,简化了与各种持久层技术(如JDBC、Hibernate、JPA等...

    数据库访问层的实现(一)——模板方法模式

    在实际开发中,为了确保代码的健壮性,还需要注意一些最佳实践,例如异常处理、资源关闭、事务管理等。在上述示例中,我们使用了`try-catch`块来捕获并处理可能抛出的`SQLException`。此外,数据库连接池(如DBCP)...

    Spring.3.x企业应用开发实战(完整版).part2

    10.5.2 Hibernate+Spring JDBC混合框架的事务管理 10.6 特殊方法成漏网之鱼 10.6.1 哪些方法不能实施Spring AOP事务 10.6.2 事务增强遗漏实例 10.7 数据连接泄漏 10.7.1 底层连接资源的访问问题 10.7.2 Spring JDBC...

    Spring3.x企业应用开发实战(完整版) part1

    10.5.2 Hibernate+Spring JDBC混合框架的事务管理 10.6 特殊方法成漏网之鱼 10.6.1 哪些方法不能实施Spring AOP事务 10.6.2 事务增强遗漏实例 10.7 数据连接泄漏 10.7.1 底层连接资源的访问问题 10.7.2 Spring JDBC...

Global site tag (gtag.js) - Google Analytics