日期:2014-05-16  浏览次数:20403 次

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) {
				TransactionSynchr