⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 toplinktransactionmanager.java

📁 Spring API核心源代码 Spring API核心源代码 Spring API核心源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:

	public Object getResourceFactory() {
		return getSessionFactory();
	}

	protected Object doGetTransaction() {
		TopLinkTransactionObject txObject = new TopLinkTransactionObject();
		SessionHolder sessionHolder = (SessionHolder)
				TransactionSynchronizationManager.getResource(this.sessionFactory);
		txObject.setSessionHolder(sessionHolder);
		return txObject;
	}

	protected boolean isExistingTransaction(Object transaction) {
		TopLinkTransactionObject txObject = (TopLinkTransactionObject) transaction;
		return (txObject.getSessionHolder() != null);
	}

	protected void doBegin(Object transaction, TransactionDefinition definition) {
		Session session = null;

		try {
			if (!definition.isReadOnly()) {
				logger.debug("Creating managed TopLink Session with active UnitOfWork for read-write transaction");
				session = getSessionFactory().createManagedClientSession();
			}
			else {
				logger.debug("Creating plain TopLink Session without active UnitOfWork for read-only transaction");
				session = getSessionFactory().createSession();
			}

			if (logger.isDebugEnabled()) {
				logger.debug("Opened new session [" + session + "] for TopLink transaction");
			}

			TopLinkTransactionObject txObject = (TopLinkTransactionObject) transaction;
			txObject.setSessionHolder(new SessionHolder(session));
			txObject.getSessionHolder().setSynchronizedWithTransaction(true);

			// Check isolation level.
			switch (definition.getIsolationLevel()) {
				case TransactionDefinition.ISOLATION_READ_UNCOMMITTED:
					// TODO warn when queries are executed without the conformResultsInUnitOfWork setting
					break;
				case TransactionDefinition.ISOLATION_REPEATABLE_READ:
					// TODO warn when queries are executed against a read-only Session
					break;
				case TransactionDefinition.ISOLATION_SERIALIZABLE:
					// TODO warn if the TransactionIsolation settings on the DatabaseLogin are wrong
					break;
			}

			// Register transaction timeout.
			int timeout = determineTimeout(definition);
			if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
				txObject.getSessionHolder().setTimeoutInSeconds(timeout);
			}

			// Enforce early database transaction for TopLink read-write transaction,
			// unless we are explicitly told to use lazy transactions.
			if (!definition.isReadOnly() && !isLazyDatabaseTransaction()) {
				session.getActiveUnitOfWork().beginEarlyTransaction();
			}

			// Register the TopLink Session's JDBC Connection for the DataSource, if set.
			if (getDataSource() != null) {
				Connection con = getJdbcConnection(session);
				if (con != null) {
					ConnectionHolder conHolder = new ConnectionHolder(con);
					if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
						conHolder.setTimeoutInSeconds(timeout);
					}
					if (logger.isDebugEnabled()) {
						logger.debug("Exposing TopLink transaction as JDBC transaction [" + con + "]");
					}
					TransactionSynchronizationManager.bindResource(getDataSource(), conHolder);
					txObject.setConnectionHolder(conHolder);
				}
				else {
					if (logger.isDebugEnabled()) {
						logger.debug("Not exposing TopLink transaction [" + session +
								"] as JDBC transaction because no JDBC Connection could be retrieved from it");
					}
				}
			}

			// Bind the session holder to the thread.
			TransactionSynchronizationManager.bindResource(getSessionFactory(), txObject.getSessionHolder());
		}

		catch (Exception ex) {
			SessionFactoryUtils.releaseSession(session, getSessionFactory());
			throw new CannotCreateTransactionException("Could not open TopLink Session for transaction", ex);
		}
	}

	/**
	 * Extract the underlying JDBC Connection from the given TopLink Session.
	 * <p>Default implementation casts to <code>oracle.toplink.publicinterface.Session</code>
	 * and fetches the Connection from the DatabaseAccessor exposed there.
	 * @param session the current TopLink Session
	 * @return the underlying JDBC Connection, or <code>null</code> if none found
	 * @see oracle.toplink.publicinterface.Session#getAccessor()
	 * @see oracle.toplink.internal.databaseaccess.DatabaseAccessor#getConnection()
	 */
	protected Connection getJdbcConnection(Session session) {
		if (!(session instanceof oracle.toplink.publicinterface.Session)) {
			if (logger.isDebugEnabled()) {
				logger.debug("TopLink Session [" + session +
						"] does not derive from [oracle.toplink.publicinterface.Session]");
			}
			return null;
		}
		Accessor accessor = ((oracle.toplink.publicinterface.Session) session).getAccessor();
		if (!(accessor instanceof DatabaseAccessor)) {
			if (logger.isDebugEnabled()) {
				logger.debug("TopLink Accessor [" + accessor +
						"] does not derive from [oracle.toplink.internal.databaseaccess.DatabaseAccessor]");
			}
			return null;
		}
		return ((DatabaseAccessor) accessor).getConnection();
	}

	protected Object doSuspend(Object transaction) {
		TopLinkTransactionObject txObject = (TopLinkTransactionObject) transaction;
		txObject.setSessionHolder(null);
		return TransactionSynchronizationManager.unbindResource(getSessionFactory());
	}

	protected void doResume(Object transaction, Object suspendedResources) {
		SessionHolder sessionHolder = (SessionHolder) suspendedResources;
		if (TransactionSynchronizationManager.hasResource(getSessionFactory())) {
			// From non-transactional code running in active transaction synchronization
			// -> can be safely removed, will be closed on transaction completion.
			TransactionSynchronizationManager.unbindResource(getSessionFactory());
		}
		TransactionSynchronizationManager.bindResource(getSessionFactory(), sessionHolder);
	}

	protected void doCommit(DefaultTransactionStatus status) {
		TopLinkTransactionObject txObject = (TopLinkTransactionObject) status.getTransaction();
		if (status.isDebug()) {
			logger.debug("Committing TopLink transaction on session [" +
					txObject.getSessionHolder().getSession() + "]");
		}
		try {
			if (!status.isReadOnly()) {
				txObject.getSessionHolder().getSession().getActiveUnitOfWork().commit();
			}
			txObject.getSessionHolder().clear();
		}
		catch (TopLinkException ex) {
			throw convertTopLinkAccessException(ex);
		}
	}

	protected void doRollback(DefaultTransactionStatus status) {
		TopLinkTransactionObject txObject = (TopLinkTransactionObject) status.getTransaction();
		if (status.isDebug()) {
			logger.debug("Not committing TopLink transaction on session [" +
					txObject.getSessionHolder().getSession() + "]");
		}
		txObject.getSessionHolder().clear();
	}

	protected void doSetRollbackOnly(DefaultTransactionStatus status) {
		TopLinkTransactionObject txObject = (TopLinkTransactionObject) status.getTransaction();
		if (status.isDebug()) {
			logger.debug("Setting TopLink transaction on session [" +
					txObject.getSessionHolder().getSession() + "] rollback-only");
		}
		txObject.getSessionHolder().setRollbackOnly();
	}

	protected void doCleanupAfterCompletion(Object transaction) {
		TopLinkTransactionObject txObject = (TopLinkTransactionObject) transaction;

		// Remove the session holder from the thread.
		TransactionSynchronizationManager.unbindResource(getSessionFactory());

		// Remove the JDBC connection holder from the thread, if exposed.
		if (txObject.hasConnectionHolder()) {
			TransactionSynchronizationManager.unbindResource(getDataSource());
		}

		Session session = txObject.getSessionHolder().getSession();
		if (logger.isDebugEnabled()) {
			logger.debug("Releasing TopLink Session [" + session + "] after transaction");
		}
		try {
			session.release();
		}
		catch (Throwable ex) {
			// just log it, to keep a transaction-related exception
			logger.debug("Could not release TopLink Session after transaction", ex);
		}
	}

	/**
	 * Convert the given TopLinkException to an appropriate exception from the
	 * <code>org.springframework.dao</code> hierarchy.
	 * <p>Will automatically apply a specified SQLExceptionTranslator to a
	 * TopLink DatabaseException, else rely on TopLink's default translation.
	 * @param ex TopLinkException that occured
	 * @return a corresponding DataAccessException
	 * @see SessionFactoryUtils#convertTopLinkAccessException
	 * @see #setJdbcExceptionTranslator
	 */
	protected DataAccessException convertTopLinkAccessException(TopLinkException ex) {
		if (getJdbcExceptionTranslator() != null && ex instanceof DatabaseException) {
			Throwable internalEx = ex.getInternalException();
			// Should always be a SQLException inside a DatabaseException.
			if (internalEx instanceof SQLException) {
				return getJdbcExceptionTranslator().translate(
						"TopLink commit: " + ex.getMessage(), null, (SQLException) internalEx);
			}
		}
		return SessionFactoryUtils.convertTopLinkAccessException(ex);
	}


	/**
	 * TopLink transaction object, representing a SessionHolder.
	 * Used as transaction object by TopLinkTransactionManager.
	 *
	 * <p>Derives from JdbcTransactionObjectSupport in order to inherit the
	 * capability to manage JDBC 3.0 Savepoints for underlying JDBC Connections.
	 */
	private static class TopLinkTransactionObject extends JdbcTransactionObjectSupport {

		private SessionHolder sessionHolder;

		public void setSessionHolder(SessionHolder sessionHolder) {
			this.sessionHolder = sessionHolder;
		}

		public SessionHolder getSessionHolder() {
			return this.sessionHolder;
		}

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

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -