jtatransactionmanager.java
来自「spring framework 2.5.4源代码」· Java 代码 · 共 1,215 行 · 第 1/4 页
JAVA
1,215 行
try {
if (logger.isDebugEnabled()) {
logger.debug("Retrieving JTA TransactionSynchronizationRegistry from JNDI location [" + registryName + "]");
}
Class registryClass = ClassUtils.forName(TRANSACTION_SYNCHRONIZATION_REGISTRY_CLASS_NAME,
JtaTransactionManager.class.getClassLoader());
return getJndiTemplate().lookup(registryName, registryClass);
}
catch (ClassNotFoundException ex) {
throw new TransactionSystemException(
"JTA 1.1 [" + TRANSACTION_SYNCHRONIZATION_REGISTRY_CLASS_NAME + "] not available");
}
catch (NamingException ex) {
throw new TransactionSystemException(
"JTA TransactionSynchronizationRegistry is not available at JNDI location [" + registryName + "]", 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;
}
/**
* Allows subclasses to retrieve the JTA 1.1 TransactionSynchronizationRegistry
* in a vendor-specific manner.
* <p>The default implementation simply returns <code>null</code>.
* @return the JTA TransactionSynchronizationRegistry handle to use,
* or <code>null</code> if none found
* @throws TransactionSystemException in case of errors
*/
protected Object retrieveTransactionSynchronizationRegistry() 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 + "]");
}
this.userTransactionObtainedFromJndi = true;
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;
}
/**
* Find the JTA 1.1 TransactionSynchronizationRegistry through autodetection:
* checking whether the UserTransaction object or TransactionManager object
* implements it, and checking Java EE 5's standard JNDI location.
* <p>The default implementation simply returns <code>null</code>.
* @param ut the JTA UserTransaction object
* @param tm the JTA TransactionManager object
* @return the JTA TransactionSynchronizationRegistry handle to use,
* or <code>null</code> if none found
* @throws TransactionSystemException in case of errors
*/
protected Object findTransactionSynchronizationRegistry(UserTransaction ut, TransactionManager tm)
throws TransactionSystemException {
try {
Class registryClass = ClassUtils.forName(TRANSACTION_SYNCHRONIZATION_REGISTRY_CLASS_NAME,
JtaTransactionManager.class.getClassLoader());
// If we came here, we might be on Java EE 5, since the JTA 1.1 API is present.
if (this.userTransactionObtainedFromJndi) {
// UserTransaction has already been obtained from JNDI, so the
// TransactionSynchronizationRegistry probably sits there as well.
String jndiName = DEFAULT_TRANSACTION_SYNCHRONIZATION_REGISTRY_NAME;
try {
Object tsr = getJndiTemplate().lookup(jndiName, registryClass);
if (logger.isDebugEnabled()) {
logger.debug("JTA TransactionSynchronizationRegistry found at default JNDI location [" + jndiName + "]");
}
return tsr;
}
catch (NamingException ex) {
if (logger.isDebugEnabled()) {
logger.debug(
"No JTA TransactionSynchronizationRegistry found at default JNDI location [" + jndiName + "]", ex);
}
}
}
// Check whether the UserTransaction or TransactionManager implements it...
if (registryClass.isInstance(ut)) {
return ut;
}
if (registryClass.isInstance(tm)) {
return tm;
}
// OK, so no JTA 1.1 TransactionSynchronizationRegistry is available,
// despite the API being present...
return null;
}
catch (ClassNotFoundException ex) {
logger.debug("JTA 1.1 [" + TRANSACTION_SYNCHRONIZATION_REGISTRY_CLASS_NAME + "] not available");
return null;
}
}
/**
* 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 (ut == null) {
throw new CannotCreateTransactionException("No JTA UserTransaction available - " +
"programmatic PlatformTransactionManager.getTransaction usage not supported");
}
if (!this.cacheUserTransaction) {
ut = lookupUserTransaction(
this.userTransactionName != null ? this.userTransactionName : DEFAULT_USER_TRANSACTION_NAME);
}
return doGetJtaTransaction(ut);
}
/**
* Get a JTA transaction object for the given current UserTransaction.
* <p>Subclasses can override this to provide a JtaTransactionObject
* subclass, for example holding some additional JTA handle needed.
* @param ut the UserTransaction handle to use for the current transaction
* @return the JtaTransactionObject holding the UserTransaction
*/
protected JtaTransactionObject doGetJtaTransaction(UserTransaction ut) {
return new JtaTransactionObject(ut);
}
protected boolean isExistingTransaction(Object transaction) {
JtaTransactionObject txObject = (JtaTransactionObject) transaction;
try {
return (txObject.getUserTransaction().getStatus() != Status.STATUS_NO_TRANSACTION);
}
catch (SystemException ex) {
throw new TransactionSystemException("JTA failure on getStatus", ex);
}
}
/**
* This implementation returns false to cause a further invocation
* of doBegin despite an already existing transaction.
* <p>JTA implementations might support nested transactions via further
* <code>UserTransaction.begin()</code> invocations, but never support savepoints.
* @see #doBegin
* @see javax.transaction.UserTransaction#begin()
*/
protected boolean useSavepointForNestedTransaction() {
return false;
}
protected void doBegin(Object transaction, TransactionDefinition definition) {
JtaTransactionObject txObject = (JtaTransactionObject) transaction;
try {
doJtaBegin(txObject, definition);
}
catch (NotSupportedException ex) {
// assume nested transaction not supported
throw new NestedTransactionNotSupportedException(
"JTA implementation does not support nested transactions", ex);
}
catch (UnsupportedOperationException ex) {
// assume nested transaction not supported
throw new NestedTransactionNotSupportedException(
"JTA implementation does not support nested transactions", ex);
}
catch (SystemException ex) {
throw new CannotCreateTransactionException("JTA failure on begin", ex);
}
}
/**
* Perform a JTA begin on the JTA UserTransaction or TransactionManager.
* <p>This implementation only supports standard JTA functionality:
* that is, no per-transaction isolation levels and no transaction names.
* Can be overridden in subclasses, for specific JTA implementations.
* <p>Calls <code>applyIsolationLevel</code> and <code>applyTimeout</code>
* before invoking the UserTransaction's <code>begin</code> method.
* @param txObject the JtaTransactionObject containing the UserTransaction
* @param definition TransactionDefinition instance, describing propagation
* behavior, isolation level, read-only flag, timeout, and transaction name
* @throws NotSupportedException if thrown by JTA methods
* @throws SystemException if thrown by JTA methods
* @see #getUserTransaction
* @see #getTransactionManager
* @see #applyIsolationLevel
* @see #applyTimeout
* @see JtaTransactionObject#getUserTransaction()
* @see javax.transaction.UserTransaction#setTransactionTimeout
* @see javax.transaction.UserTransaction#begin
*/
protected void doJtaBegin(JtaTransactionObject txObject, TransactionDefinition definition)
throws NotSupportedException, SystemException {
applyIsolationLevel(txObject, definition.getIsolationLevel());
int timeout = determineTimeout(definition);
applyTimeout(txObject, timeout);
txObject.getUserTransaction().begin();
}
/**
* Apply the given transaction isolation level. The default implementation
* will throw an exception for any level other than ISOLATION_DEFAULT.
* <p>To be overridden in subclasses for specific JTA implementations,
* as alternative to overriding the full {@link #doJtaBegin} method.
* @param txObject the JtaTransactionObject containing the UserTransaction
* @param isolationLevel isolation level taken from transaction definition
* @throws InvalidIsolationLevelException if the given isolation level
* cannot be applied
* @throws SystemException if thrown by the JTA implementation
* @see #doJtaBegin
* @see JtaTransactionObject#getUserTransaction()
* @see #getTransactionManager()
*/
protected void applyIsolationLevel(JtaTransactionObject txObject, int isolationLevel)
throws InvalidIsolationLevelException, SystemException {
if (!this.allowCustomIsolationLevels && isolationLevel != TransactionDefinition.ISOLATION_DEFAULT) {
throw new InvalidIsolationLevelException(
"JtaTransactionManager does not support custom isolation levels by default - " +
"switch 'allowCustomIsolationLevels' to 'true'");
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?