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

📄 jtatransactionmanager.java

📁 Spring API核心源代码 Spring API核心源代码 Spring API核心源代码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
	 * <p>Default is "true": UserTransaction lookup will only happen at startup,
	 * reusing the same UserTransaction handle for all transactions of all threads.
	 * This is the most efficient choice for all application servers that provide
	 * a shared UserTransaction object (the typical case).
	 * <p>Turn this flag off to enforce a fresh lookup of the UserTransaction
	 * for every transaction. This is only necessary for application servers
	 * that return a new UserTransaction for every transaction, keeping state
	 * tied to the UserTransaction object itself rather than the current thread.
	 * @see #setUserTransactionName
	 */
	public void setCacheUserTransaction(boolean cacheUserTransaction) {
		this.cacheUserTransaction = cacheUserTransaction;
	}


	/**
	 * Set the JTA TransactionManager to use as direct reference.
	 * <p>A TransactionManager is necessary for suspending and resuming transactions,
	 * as this not supported by the UserTransaction interface.
	 * <p>Note that the TransactionManager will be autodetected if the JTA
	 * UserTransaction object implements the JTA TransactionManager interface too,
	 * as well as autodetected at various well-known fallback JNDI locations.
	 * @see #setTransactionManagerName
	 * @see #setAutodetectTransactionManager
	 */
	public void setTransactionManager(TransactionManager transactionManager) {
		this.transactionManager = transactionManager;
	}

	/**
	 * Return the JTA TransactionManager that this transaction manager uses.
	 */
	public TransactionManager getTransactionManager() {
		return this.transactionManager;
	}

	/**
	 * Set the JNDI name of the JTA TransactionManager.
	 * <p>A TransactionManager is necessary for suspending and resuming transactions,
	 * as this not supported by the UserTransaction interface.
	 * <p>Note that the TransactionManager will be autodetected if the JTA
	 * UserTransaction object implements the JTA TransactionManager interface too,
	 * as well as autodetected at various well-known fallback JNDI locations.
	 * @see #setTransactionManager
	 * @see #setAutodetectTransactionManager
	 */
	public void setTransactionManagerName(String transactionManagerName) {
		this.transactionManagerName = transactionManagerName;
	}

	/**
	 * Set whether to autodetect a JTA UserTransaction object that implements
	 * the JTA TransactionManager interface too (i.e. the JNDI location for the
	 * TransactionManager is "java:comp/UserTransaction", same as for the UserTransaction).
	 * Also checks the fallback JNDI locations "java:comp/TransactionManager" and
	 * "java:/TransactionManager". Will proceed without TransactionManager if none found.
	 * <p>Default is "true", autodetecting the TransactionManager unless it has been
	 * specified explicitly. Can be turned off to deliberately ignore an available
	 * TransactionManager, for example when there are known issues with suspend/resume
	 * and any attempt to use REQUIRES_NEW or NOT_SUPPORTED should fail fast.
	 * @see #FALLBACK_TRANSACTION_MANAGER_NAMES
	 */
	public void setAutodetectTransactionManager(boolean autodetectTransactionManager) {
		this.autodetectTransactionManager = autodetectTransactionManager;
	}

	/**
	 * Set whether to allow custom isolation levels to be specified.
	 * <p>Default is "false", throwing an exception if a non-default isolation level
	 * is specified for a transaction. Turn this flag on if affected resource adapters
	 * check the thread-bound transaction context and apply the specified isolation
	 * levels individually (e.g. through a IsolationLevelDataSourceRouter).
	 * @see org.springframework.jdbc.datasource.lookup.IsolationLevelDataSourceRouter
	 */
	public void setAllowCustomIsolationLevels(boolean allowCustomIsolationLevels) {
		this.allowCustomIsolationLevels = allowCustomIsolationLevels;
	}


	/**
	 * Initialize the UserTransaction as well as the TransactionManager handle.
	 * @see #initUserTransactionAndTransactionManager()
	 */
	public void afterPropertiesSet() throws TransactionSystemException {
		initUserTransactionAndTransactionManager();
	}

	/**
	 * Initialize the UserTransaction as well as the TransactionManager handle.
	 * @throws TransactionSystemException if initialization failed
	 */
	protected void initUserTransactionAndTransactionManager() throws TransactionSystemException {
		// Fetch JTA UserTransaction from JNDI, if necessary.
		if (this.userTransaction == null) {
			if (this.userTransactionName != null) {
				this.userTransaction = lookupUserTransaction(this.userTransactionName);
			}
			else {
				this.userTransaction = retrieveUserTransaction();
			}
		}

		// Fetch JTA TransactionManager from JNDI, if necessary.
		if (this.transactionManager == null) {
			if (this.transactionManagerName != null) {
				this.transactionManager = lookupTransactionManager(this.transactionManagerName);
			}
			else {
				this.transactionManager = retrieveTransactionManager();
			}
		}

		// Autodetect UserTransaction at its default JNDI location.
		if (this.userTransaction == null && this.autodetectUserTransaction) {
			this.userTransaction = findUserTransaction();
		}

		// Autodetect UserTransaction object that implements TransactionManager,
		// and check fallback JNDI locations else.
		if (this.transactionManager == null && this.autodetectTransactionManager) {
			this.transactionManager = findTransactionManager(this.userTransaction);
		}

		// If only JTA TransactionManager specified, create UserTransaction handle for it.
		if (this.userTransaction == null && this.transactionManager != null) {
			this.userTransaction = buildUserTransaction(this.transactionManager);
		}

		// We at least need the JTA UserTransaction.
		if (this.userTransaction != null) {
			if (logger.isInfoEnabled()) {
				logger.info("Using JTA UserTransaction: " + this.userTransaction);
			}
		}
		else {
			throw new IllegalStateException(
					"Either 'userTransaction' or 'userTransactionName' or 'transactionManager' " +
					"or 'transactionManagerName' must be specified");
		}

		// For transaction suspension, the JTA TransactionManager is necessary too.
		if (this.transactionManager != null) {
			if (logger.isInfoEnabled()) {
				logger.info("Using JTA TransactionManager: " + this.transactionManager);
			}
		}
		else {
			logger.warn("No JTA TransactionManager found: " +
					"transaction suspension and synchronization with existing JTA transactions not available");
		}
	}


	/**
	 * Look up the JTA UserTransaction in JNDI via the configured name.
	 * Called by <code>afterPropertiesSet</code> if no direct UserTransaction reference was set.
	 * Can be overridden in subclasses to provide a different UserTransaction object.
	 * @param userTransactionName the JNDI name of the UserTransaction
	 * @return the UserTransaction object
	 * @throws TransactionSystemException if the JNDI lookup failed
	 * @see #setJndiTemplate
	 * @see #setUserTransactionName
	 */
	protected UserTransaction lookupUserTransaction(String userTransactionName)
			throws TransactionSystemException {
		try {
			if (logger.isDebugEnabled()) {
				logger.debug("Retrieving JTA UserTransaction from JNDI location [" + userTransactionName + "]");
			}
			return (UserTransaction) getJndiTemplate().lookup(userTransactionName, UserTransaction.class);
		}
		catch (NamingException ex) {
			throw new TransactionSystemException(
					"JTA UserTransaction is not available at JNDI location [" + userTransactionName + "]", ex);
		}
	}

	/**
	 * Look up the JTA TransactionManager in JNDI via the configured name.
	 * Called by <code>afterPropertiesSet</code> if no direct TransactionManager reference was set.
	 * Can be overridden in subclasses to provide a different TransactionManager object.
	 * @param transactionManagerName the JNDI name of the TransactionManager
	 * @return the UserTransaction object
	 * @throws TransactionSystemException if the JNDI lookup failed
	 * @see #setJndiTemplate
	 * @see #setTransactionManagerName
	 */
	protected TransactionManager lookupTransactionManager(String transactionManagerName)
			throws TransactionSystemException {
		try {
			if (logger.isDebugEnabled()) {
				logger.debug("Retrieving JTA TransactionManager from JNDI location [" + transactionManagerName + "]");
			}
			return (TransactionManager) getJndiTemplate().lookup(transactionManagerName, TransactionManager.class);
		}
		catch (NamingException ex) {
			throw new TransactionSystemException(
					"JTA TransactionManager is not available at JNDI location [" + transactionManagerName + "]", ex);
		}
	}

	/**
	 * Allows subclasses to retrieve the JTA UserTransaction in a vendor-specific manner.
	 * Only called if no "userTransaction" or "userTransactionName" specified.
	 * <p>The default implementation simply returns <code>null</code>.
	 * @return the JTA UserTransaction handle to use, or <code>null</code> if none found
	 * @throws TransactionSystemException in case of errors
	 * @see #setUserTransaction
	 * @see #setUserTransactionName
	 */
	protected UserTransaction retrieveUserTransaction() throws TransactionSystemException {
		return null;
	}

	/**
	 * Allows subclasses to retrieve the JTA TransactionManager in a vendor-specific manner.
	 * Only called if no "transactionManager" or "transactionManagerName" specified.
	 * <p>The default implementation simply returns <code>null</code>.
	 * @return the JTA TransactionManager handle to use, or <code>null</code> if none found
	 * @throws TransactionSystemException in case of errors
	 * @see #setTransactionManager
	 * @see #setTransactionManagerName
	 */
	protected TransactionManager retrieveTransactionManager() throws TransactionSystemException {
		return null;
	}

	/**
	 * Find the JTA UserTransaction through a default JNDI lookup:
	 * "java:comp/UserTransaction".
	 * @return the JTA UserTransaction reference, or <code>null</code> if not found
	 * @see #DEFAULT_USER_TRANSACTION_NAME
	 */
	protected UserTransaction findUserTransaction() {
		String jndiName = DEFAULT_USER_TRANSACTION_NAME;
		try {
			UserTransaction ut = (UserTransaction) getJndiTemplate().lookup(jndiName, UserTransaction.class);
			if (logger.isDebugEnabled()) {
				logger.debug("JTA UserTransaction found at default JNDI location [" + jndiName + "]");
			}
			return ut;
		}
		catch (NamingException ex) {
			if (logger.isDebugEnabled()) {
				logger.debug("No JTA UserTransaction found at default JNDI location [" + jndiName + "]", ex);
			}
			return null;
		}
	}

	/**
	 * Find the JTA TransactionManager through autodetection: checking whether the
	 * UserTransaction object implements the TransactionManager, and checking the
	 * fallback JNDI locations.
	 * @param ut the JTA UserTransaction object
	 * @return the JTA TransactionManager reference, or <code>null</code> if not found
	 * @see #FALLBACK_TRANSACTION_MANAGER_NAMES
	 */
	protected TransactionManager findTransactionManager(UserTransaction ut) {
		if (ut instanceof TransactionManager) {
			if (logger.isDebugEnabled()) {
				logger.debug("JTA UserTransaction object [" + ut + "] implements TransactionManager");
			}
			return (TransactionManager) ut;
		}

		// Check fallback JNDI locations.
		for (int i = 0; i < FALLBACK_TRANSACTION_MANAGER_NAMES.length; i++) {
			String jndiName = FALLBACK_TRANSACTION_MANAGER_NAMES[i];
			try {
				TransactionManager tm = (TransactionManager) getJndiTemplate().lookup(jndiName, TransactionManager.class);
				if (logger.isDebugEnabled()) {
					logger.debug("JTA TransactionManager found at fallback JNDI location [" + jndiName + "]");
				}
				return tm;
			}
			catch (NamingException ex) {
				if (logger.isDebugEnabled()) {
					logger.debug("No JTA TransactionManager found at fallback JNDI location [" + jndiName + "]", ex);
				}
			}
		}

		// OK, so no JTA TransactionManager is available...
		return null;
	}

	/**
	 * Build a UserTransaction handle based on the given TransactionManager.
	 * @param transactionManager the TransactionManager
	 * @return a corresponding UserTransaction handle
	 */
	protected UserTransaction buildUserTransaction(TransactionManager transactionManager) {
		if (transactionManager instanceof UserTransaction) {
			return (UserTransaction) transactionManager;
		}
		else {
			return new UserTransactionAdapter(transactionManager);
		}
	}


	/**
	 * This implementation returns a JtaTransactionObject instance for the
	 * JTA UserTransaction.
	 * <p>The UserTransaction object will either be looked up freshly for the
	 * current transaction, or the cached one looked up at startup will be used.
	 * The latter is the default: Most application servers use a shared singleton
	 * UserTransaction that can be cached. Turn off the "cacheUserTransaction"
	 * flag to enforce a fresh lookup for every transaction.
	 * @see #setCacheUserTransaction
	 */
	protected Object doGetTransaction() {
		UserTransaction ut = getUserTransaction();
		if (!this.cacheUserTransaction) {
			ut = lookupUserTransaction(
					this.userTransactionName != null ? this.userTransactionName : DEFAULT_USER_TRANSACTION_NAME);
		}
		return doGetJtaTransaction(ut);
	}

	/**

⌨️ 快捷键说明

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