org.springframework.transaction.jta
Class JtaTransactionManager

java.lang.Object
  extended byorg.springframework.transaction.support.AbstractPlatformTransactionManager
      extended byorg.springframework.transaction.jta.JtaTransactionManager
All Implemented Interfaces:
InitializingBean, PlatformTransactionManager

public class JtaTransactionManager
extends AbstractPlatformTransactionManager
implements InitializingBean

PlatformTransactionManager implementation for JTA, i.e. J2EE container transactions. Can also work with a locally configured JTA implementation.

This transaction manager is appropriate for handling distributed transactions, i.e. transactions that span multiple resources, and for managing transactions on a J2EE Connector (e.g. a persistence toolkit registered as JCA Connector). For a single JDBC DataSource, DataSourceTransactionManager is perfectly sufficient, and for accessing a single resource with Hibernate (including transactional cache), HibernateTransactionManager is appropriate.

Transaction synchronization is active by default, to allow data access support classes to register resources that are opened within the transaction for closing at transaction completion time. Spring's support classes for JDBC, Hibernate and JDO all perform such registration, allowing for reuse of the same Hibernate Session etc within the transaction. Standard JTA does not even guarantee that for Connections from a transactional JDBC DataSource: Spring's synchronization solves those issues.

Synchronization is also leveraged for transactional cache handling with Hibernate. Therefore, as long as JtaTransactionManager drives the JTA transactions, there is no need to configure Hibernate's JTATransaction strategy or a container-specific Hibernate TransactionManagerLookup. However, certain JTA implementations are restrictive in terms of what JDBC calls they allow after transaction completion, complaining even on close calls: In that case, it is indeed necessary to configure a Hibernate TransactionManagerLookup; Spring will automatically adapt to this.

If JtaTransactionManager participates in an existing JTA transaction, e.g. from EJB CMT, synchronization will be triggered on finishing the nested transaction, before passing transaction control back to the J2EE container. In this case, a container-specific Hibernate TransactionManagerLookup is the only way to achieve exact afterCompletion callbacks for transactional cache handling with Hibernate. In such a scenario, use Hibernate >=2.1 which features automatic JTA detection.

Transaction suspension (REQUIRES_NEW, NOT_SUPPORTED) is just available with a JTA TransactionManager being registered, via the "transactionManagerName" or "transactionManager" property. The location of this internal JTA object is not specified by J2EE; it is individual for each J2EE server, often kept in JNDI like the UserTransaction. Some well-known JNDI locations are:

"java:comp/UserTransaction" as JNDI name for the TransactionManager means that the same JTA object implements both the UserTransaction and the TransactionManager interface. As this is easy to test when looking up the UserTransaction, this will be auto-detected on initialization of JtaTransactionManager. Thus, there's no need to specify the "transactionManagerName" in this case (for Resin, Orion, JOnAS).

For IBM WebSphere and standalone JOTM, static accessor methods are required to obtain the JTA TransactionManager: Therefore, WebSphere and JOTM have their own FactoryBean implementations, to be wired with the "transactionManager" property. In case of JotmFactoryBean, the same JTA object implements UserTransaction too: Therefore, passing the object to the "userTransaction" property is sufficient.

The internal JTA TransactionManager can also be used to register custom synchronizations with the JTA transaction itself instead of Spring's transaction manager. LocalSessionFactoryBean supports plugging a given TransactionManager into Hibernate's TransactionManagerLookup mechanism, for Hibernate-driven cache synchronization without double configuration.

JtaTransactionManager supports timeouts but not custom isolation levels. Custom subclasses can override applyIsolationLevel for specific JTA implementations. Note that some resource-specific transaction managers like DataSourceTransactionManager and HibernateTransactionManager do support timeouts, custom isolation levels, and transaction suspension without JTA's restrictions.

Since:
24.03.2003
Author:
Juergen Hoeller
See Also:
setUserTransactionName(java.lang.String), setTransactionManagerName(java.lang.String), applyIsolationLevel(int), JotmFactoryBean, WebSphereTransactionManagerFactoryBean, LocalSessionFactoryBean.setJtaTransactionManager(javax.transaction.TransactionManager), HibernateTransactionManager, DataSourceTransactionManager

Field Summary
static java.lang.String DEFAULT_USER_TRANSACTION_NAME
           
 
Fields inherited from class org.springframework.transaction.support.AbstractPlatformTransactionManager
logger, SYNCHRONIZATION_ALWAYS, SYNCHRONIZATION_NEVER, SYNCHRONIZATION_ON_ACTUAL_TRANSACTION
 
Constructor Summary
JtaTransactionManager()
           
 
Method Summary
 void afterPropertiesSet()
          Invoked by a BeanFactory after it has set all bean properties supplied (and satisfied BeanFactoryAware and ApplicationContextAware).
protected  void applyIsolationLevel(int isolationLevel)
          Apply the given transaction isolation level.
protected  void doBegin(java.lang.Object transaction, TransactionDefinition definition)
          Begin a new transaction with the given transaction definition.
protected  void doCleanupAfterCompletion(java.lang.Object transaction)
          Cleanup resources after transaction completion.
protected  void doCommit(DefaultTransactionStatus status)
          Perform an actual commit on the given transaction.
protected  java.lang.Object doGetTransaction()
          Return a current transaction object, i.e.
protected  void doResume(java.lang.Object transaction, java.lang.Object suspendedResources)
          Resume the resources of the current transaction.
protected  void doRollback(DefaultTransactionStatus status)
          Perform an actual rollback on the given transaction.
protected  void doSetRollbackOnly(DefaultTransactionStatus status)
          Set the given transaction rollback-only.
protected  java.lang.Object doSuspend(java.lang.Object transaction)
          Suspend the resources of the current transaction.
protected  boolean isExistingTransaction(java.lang.Object transaction)
          Check if the given transaction object indicates an existing, i.e.
protected  boolean isRollbackOnly(java.lang.Object transaction)
          Check if the given transaction object indicates a rollback-only, assumably from a nested transaction (else, the TransactionStatus of this transaction would have indicated rollback-only).
protected  javax.transaction.TransactionManager lookupTransactionManager(java.lang.String transactionManagerName)
          Look up the JTA TransactionManager in JNDI via the configured name.
protected  javax.transaction.UserTransaction lookupUserTransaction(java.lang.String userTransactionName)
          Look up the JTA UserTransaction in JNDI via the configured name.
 void setJndiTemplate(JndiTemplate jndiTemplate)
          Set the JndiTemplate to use for JNDI lookups.
 void setTransactionManager(javax.transaction.TransactionManager transactionManager)
          Set the JTA TransactionManager to use as direct reference.
 void setTransactionManagerName(java.lang.String transactionManagerName)
          Set the JNDI name of the JTA TransactionManager.
 void setUserTransaction(javax.transaction.UserTransaction userTransaction)
          Set the JTA UserTransaction to use as direct reference.
 void setUserTransactionName(java.lang.String userTransactionName)
          Set the JNDI name of the JTA UserTransaction.
 
Methods inherited from class org.springframework.transaction.support.AbstractPlatformTransactionManager
commit, getTransaction, getTransactionSynchronization, isRollbackOnCommitFailure, rollback, setRollbackOnCommitFailure, setTransactionSynchronization, setTransactionSynchronizationName
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

DEFAULT_USER_TRANSACTION_NAME

public static final java.lang.String DEFAULT_USER_TRANSACTION_NAME
See Also:
Constant Field Values
Constructor Detail

JtaTransactionManager

public JtaTransactionManager()
Method Detail

setJndiTemplate

public void setJndiTemplate(JndiTemplate jndiTemplate)
Set the JndiTemplate to use for JNDI lookups. A default one is used if not set.


setUserTransaction

public void setUserTransaction(javax.transaction.UserTransaction userTransaction)
Set the JTA UserTransaction to use as direct reference. Typically just used for local JTA setups; in a J2EE environment, the UserTransaction will always be fetched from JNDI.


setUserTransactionName

public void setUserTransactionName(java.lang.String userTransactionName)
Set the JNDI name of the JTA UserTransaction. The default one is used if not set.

See Also:
DEFAULT_USER_TRANSACTION_NAME

setTransactionManager

public void setTransactionManager(javax.transaction.TransactionManager transactionManager)
Set the JTA TransactionManager to use as direct reference.

A TransactionManager is necessary for suspending and resuming transactions, as this not supported by the UserTransaction interface.


setTransactionManagerName

public void setTransactionManagerName(java.lang.String transactionManagerName)
Set the JNDI name of the JTA TransactionManager.

A TransactionManager is necessary for suspending and resuming transactions, as this not supported by the UserTransaction interface.


afterPropertiesSet

public void afterPropertiesSet()
                        throws CannotCreateTransactionException
Description copied from interface: InitializingBean
Invoked by a BeanFactory after it has set all bean properties supplied (and satisfied BeanFactoryAware and ApplicationContextAware).

This method allows the bean instance to perform initialization only possible when all bean properties have been set and to throw an exception in the event of misconfiguration.

Specified by:
afterPropertiesSet in interface InitializingBean
Throws:
CannotCreateTransactionException

lookupUserTransaction

protected javax.transaction.UserTransaction lookupUserTransaction(java.lang.String userTransactionName)
                                                           throws CannotCreateTransactionException
Look up the JTA UserTransaction in JNDI via the configured name. Called by afterPropertiesSet if no direct UserTransaction reference was set. Can be overridden in subclasses to provide a different UserTransaction object.

Parameters:
userTransactionName - the JNDI name of the UserTransaction
Returns:
the UserTransaction object
Throws:
CannotCreateTransactionException - if the JNDI lookup failed
See Also:
setJndiTemplate(org.springframework.jndi.JndiTemplate), setUserTransactionName(java.lang.String)

lookupTransactionManager

protected javax.transaction.TransactionManager lookupTransactionManager(java.lang.String transactionManagerName)
                                                                 throws CannotCreateTransactionException
Look up the JTA TransactionManager in JNDI via the configured name. Called by afterPropertiesSet if no direct TransactionManager reference was set. Can be overridden in subclasses to provide a different TransactionManager object.

Parameters:
transactionManagerName - the JNDI name of the TransactionManager
Returns:
the UserTransaction object
Throws:
CannotCreateTransactionException - if the JNDI lookup failed
See Also:
setJndiTemplate(org.springframework.jndi.JndiTemplate), setTransactionManagerName(java.lang.String)

doGetTransaction

protected java.lang.Object doGetTransaction()
Description copied from class: AbstractPlatformTransactionManager
Return a current transaction object, i.e. a JTA UserTransaction.

Specified by:
doGetTransaction in class AbstractPlatformTransactionManager
Returns:
the current transaction object

isExistingTransaction

protected boolean isExistingTransaction(java.lang.Object transaction)
Description copied from class: AbstractPlatformTransactionManager
Check if the given transaction object indicates an existing, i.e. already begun, transaction.

Specified by:
isExistingTransaction in class AbstractPlatformTransactionManager
Parameters:
transaction - transaction object returned by doGetTransaction
Returns:
if there is an existing transaction

doBegin

protected void doBegin(java.lang.Object transaction,
                       TransactionDefinition definition)
Description copied from class: AbstractPlatformTransactionManager
Begin a new transaction with the given transaction definition. Does not have to care about applying the propagation behavior, as this has already been handled by this abstract manager.

Specified by:
doBegin in class AbstractPlatformTransactionManager
Parameters:
transaction - transaction object returned by doGetTransaction
definition - TransactionDefinition instance, describing propagation behavior, isolation level, timeout etc.

applyIsolationLevel

protected void applyIsolationLevel(int isolationLevel)
                            throws InvalidIsolationLevelException
Apply the given transaction isolation level. Default implementation will throw an exception for any level other than ISOLATION_DEFAULT. To be overridden in subclasses for specific JTA implementations.

Parameters:
isolationLevel - isolation level taken from transaction definition
Throws:
InvalidIsolationLevelException - if the given isolation level cannot be applied

doSuspend

protected java.lang.Object doSuspend(java.lang.Object transaction)
Description copied from class: AbstractPlatformTransactionManager
Suspend the resources of the current transaction. Transaction synchronization will already have been suspended.

Specified by:
doSuspend in class AbstractPlatformTransactionManager
Parameters:
transaction - transaction object returned by doGetTransaction
Returns:
an object that holds suspended resources (will be kept unexamined for passing it into doResume)
See Also:
AbstractPlatformTransactionManager.doResume(java.lang.Object, java.lang.Object)

doResume

protected void doResume(java.lang.Object transaction,
                        java.lang.Object suspendedResources)
Description copied from class: AbstractPlatformTransactionManager
Resume the resources of the current transaction. Transaction synchronization will be resumed afterwards.

Specified by:
doResume in class AbstractPlatformTransactionManager
Parameters:
transaction - transaction object returned by doGetTransaction
suspendedResources - the object that holds suspended resources, as returned by doSuspend
See Also:
AbstractPlatformTransactionManager.doSuspend(java.lang.Object)

isRollbackOnly

protected boolean isRollbackOnly(java.lang.Object transaction)
                          throws TransactionException
Description copied from class: AbstractPlatformTransactionManager
Check if the given transaction object indicates a rollback-only, assumably from a nested transaction (else, the TransactionStatus of this transaction would have indicated rollback-only).

Specified by:
isRollbackOnly in class AbstractPlatformTransactionManager
Parameters:
transaction - transaction object returned by doGetTransaction
Returns:
if the transaction has to result in a rollback
Throws:
TransactionException - in case of creation or system errors

doCommit

protected void doCommit(DefaultTransactionStatus status)
Description copied from class: AbstractPlatformTransactionManager
Perform an actual commit on the given transaction. An implementation does not need to check the rollback-only flag.

Specified by:
doCommit in class AbstractPlatformTransactionManager
Parameters:
status - status representation of the transaction

doRollback

protected void doRollback(DefaultTransactionStatus status)
Description copied from class: AbstractPlatformTransactionManager
Perform an actual rollback on the given transaction. An implementation does not need to check the new transaction flag.

Specified by:
doRollback in class AbstractPlatformTransactionManager
Parameters:
status - status representation of the transaction

doSetRollbackOnly

protected void doSetRollbackOnly(DefaultTransactionStatus status)
Description copied from class: AbstractPlatformTransactionManager
Set the given transaction rollback-only. Only called on rollback if the current transaction takes part in an existing one.

Specified by:
doSetRollbackOnly in class AbstractPlatformTransactionManager
Parameters:
status - status representation of the transaction

doCleanupAfterCompletion

protected void doCleanupAfterCompletion(java.lang.Object transaction)
Description copied from class: AbstractPlatformTransactionManager
Cleanup resources after transaction completion. Called after doCommit and doRollback execution on any outcome. Should not throw any exceptions but just issue warnings on errors.

Specified by:
doCleanupAfterCompletion in class AbstractPlatformTransactionManager
Parameters:
transaction - transaction object returned by doGetTransaction


Copyright (C) 2003-2004 The Spring Framework Project.