spring-jdbc

org.springframework.jdbc.datasource
Class DataSourceTransactionManager

java.lang.Object
  extended by org.springframework.transaction.support.AbstractPlatformTransactionManager
      extended by org.springframework.jdbc.datasource.DataSourceTransactionManager
All Implemented Interfaces:
java.io.Serializable, org.springframework.beans.factory.InitializingBean, org.springframework.transaction.PlatformTransactionManager, org.springframework.transaction.support.ResourceTransactionManager

public class DataSourceTransactionManager
extends org.springframework.transaction.support.AbstractPlatformTransactionManager
implements org.springframework.transaction.support.ResourceTransactionManager, org.springframework.beans.factory.InitializingBean

PlatformTransactionManager implementation for a single JDBC DataSource. This class is capable of working in any environment with any JDBC driver, as long as the setup uses a JDBC 2.0 Standard Extensions / JDBC 3.0 javax.sql.DataSource as its Connection factory mechanism. Binds a JDBC Connection from the specified DataSource to the current thread, potentially allowing for one thread-bound Connection per DataSource.

Note: The DataSource that this transaction manager operates on needs to return independent Connections. The Connections may come from a pool (the typical case), but the DataSource must not return thread-scoped / request-scoped Connections or the like. This transaction manager will associate Connections with thread-bound transactions itself, according to the specified propagation behavior. It assumes that a separate, independent Connection can be obtained even during an ongoing transaction.

Application code is required to retrieve the JDBC Connection via DataSourceUtils.getConnection(DataSource) instead of a standard J2EE-style DataSource.getConnection() call. Spring classes such as JdbcTemplate use this strategy implicitly. If not used in combination with this transaction manager, the DataSourceUtils lookup strategy behaves exactly like the native DataSource lookup; it can thus be used in a portable fashion.

Alternatively, you can allow application code to work with the standard J2EE-style lookup pattern DataSource.getConnection(), for example for legacy code that is not aware of Spring at all. In that case, define a TransactionAwareDataSourceProxy for your target DataSource, and pass that proxy DataSource to your DAOs, which will automatically participate in Spring-managed transactions when accessing it.

Supports custom isolation levels, and timeouts which get applied as appropriate JDBC statement timeouts. To support the latter, application code must either use JdbcTemplate, call DataSourceUtils.applyTransactionTimeout(java.sql.Statement, javax.sql.DataSource) for each created JDBC Statement, or go through a TransactionAwareDataSourceProxy which will create timeout-aware JDBC Connections and Statements automatically.

Consider defining a LazyConnectionDataSourceProxy for your target DataSource, pointing both this transaction manager and your DAOs to it. This will lead to optimized handling of "empty" transactions, i.e. of transactions without any JDBC statements executed. A LazyConnectionDataSourceProxy will not fetch an actual JDBC Connection from the target DataSource until a Statement gets executed, lazily applying the specified transaction settings to the target Connection.

On JDBC 3.0, this transaction manager supports nested transactions via the JDBC 3.0 Savepoint mechanism. The "nestedTransactionAllowed" flag defaults to "true", since nested transactions will work without restrictions on JDBC drivers that support savepoints (such as the Oracle JDBC driver).

This transaction manager can be used as a replacement for the org.springframework.transaction.jta.JtaTransactionManager in the single resource case, as it does not require a container that supports JTA, typically in combination with a locally defined JDBC DataSource (e.g. a Jakarta Commons DBCP connection pool). Switching between this local strategy and a JTA environment is just a matter of configuration!

Since:
02.05.2003
Author:
Juergen Hoeller
See Also:
AbstractPlatformTransactionManager.setNestedTransactionAllowed(boolean), Savepoint, DataSourceUtils.getConnection(javax.sql.DataSource), DataSourceUtils.applyTransactionTimeout(java.sql.Statement, javax.sql.DataSource), DataSourceUtils.releaseConnection(java.sql.Connection, javax.sql.DataSource), TransactionAwareDataSourceProxy, LazyConnectionDataSourceProxy, JdbcTemplate, Serialized Form

Nested Class Summary
 
Nested classes/interfaces inherited from class org.springframework.transaction.support.AbstractPlatformTransactionManager
org.springframework.transaction.support.AbstractPlatformTransactionManager.SuspendedResourcesHolder
 
Field Summary
 
Fields inherited from class org.springframework.transaction.support.AbstractPlatformTransactionManager
logger, SYNCHRONIZATION_ALWAYS, SYNCHRONIZATION_NEVER, SYNCHRONIZATION_ON_ACTUAL_TRANSACTION
 
Constructor Summary
DataSourceTransactionManager()
          Create a new DataSourceTransactionManager instance.
DataSourceTransactionManager(javax.sql.DataSource dataSource)
          Create a new DataSourceTransactionManager instance.
 
Method Summary
 void afterPropertiesSet()
           
protected  void doBegin(java.lang.Object transaction, org.springframework.transaction.TransactionDefinition definition)
          This implementation sets the isolation level but ignores the timeout.
protected  void doCleanupAfterCompletion(java.lang.Object transaction)
           
protected  void doCommit(org.springframework.transaction.support.DefaultTransactionStatus status)
           
protected  java.lang.Object doGetTransaction()
           
protected  void doResume(java.lang.Object transaction, java.lang.Object suspendedResources)
           
protected  void doRollback(org.springframework.transaction.support.DefaultTransactionStatus status)
           
protected  void doSetRollbackOnly(org.springframework.transaction.support.DefaultTransactionStatus status)
           
protected  java.lang.Object doSuspend(java.lang.Object transaction)
           
 javax.sql.DataSource getDataSource()
          Return the JDBC DataSource that this instance manages transactions for.
 java.lang.Object getResourceFactory()
           
protected  boolean isExistingTransaction(java.lang.Object transaction)
           
 void setDataSource(javax.sql.DataSource dataSource)
          Set the JDBC DataSource that this instance should manage transactions for.
 
Methods inherited from class org.springframework.transaction.support.AbstractPlatformTransactionManager
commit, determineTimeout, getDefaultTimeout, getTransaction, getTransactionSynchronization, invokeAfterCompletion, isFailEarlyOnGlobalRollbackOnly, isGlobalRollbackOnParticipationFailure, isNestedTransactionAllowed, isRollbackOnCommitFailure, isValidateExistingTransaction, newTransactionStatus, prepareForCommit, prepareSynchronization, prepareTransactionStatus, registerAfterCompletionWithExistingTransaction, resume, rollback, setDefaultTimeout, setFailEarlyOnGlobalRollbackOnly, setGlobalRollbackOnParticipationFailure, setNestedTransactionAllowed, setRollbackOnCommitFailure, setTransactionSynchronization, setTransactionSynchronizationName, setValidateExistingTransaction, shouldCommitOnGlobalRollbackOnly, suspend, triggerBeforeCommit, triggerBeforeCompletion, useSavepointForNestedTransaction
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface org.springframework.transaction.PlatformTransactionManager
commit, getTransaction, rollback
 

Constructor Detail

DataSourceTransactionManager

public DataSourceTransactionManager()
Create a new DataSourceTransactionManager instance. A DataSource has to be set to be able to use it.

See Also:
setDataSource(javax.sql.DataSource)

DataSourceTransactionManager

public DataSourceTransactionManager(javax.sql.DataSource dataSource)
Create a new DataSourceTransactionManager instance.

Parameters:
dataSource - JDBC DataSource to manage transactions for
Method Detail

setDataSource

public void setDataSource(javax.sql.DataSource dataSource)
Set the JDBC DataSource that this instance should manage transactions for.

This will typically be a locally defined DataSource, for example a Jakarta Commons DBCP connection pool. Alternatively, you can also drive transactions for a non-XA J2EE DataSource fetched from JNDI. For an XA DataSource, use JtaTransactionManager.

The DataSource specified here should be the target DataSource to manage transactions for, not a TransactionAwareDataSourceProxy. Only data access code may work with TransactionAwareDataSourceProxy, while the transaction manager needs to work on the underlying target DataSource. If there's nevertheless a TransactionAwareDataSourceProxy passed in, it will be unwrapped to extract its target DataSource.

The DataSource passed in here needs to return independent Connections. The Connections may come from a pool (the typical case), but the DataSource must not return thread-scoped / request-scoped Connections or the like.

See Also:
TransactionAwareDataSourceProxy, org.springframework.transaction.jta.JtaTransactionManager

getDataSource

public javax.sql.DataSource getDataSource()
Return the JDBC DataSource that this instance manages transactions for.


afterPropertiesSet

public void afterPropertiesSet()
Specified by:
afterPropertiesSet in interface org.springframework.beans.factory.InitializingBean

getResourceFactory

public java.lang.Object getResourceFactory()
Specified by:
getResourceFactory in interface org.springframework.transaction.support.ResourceTransactionManager

doGetTransaction

protected java.lang.Object doGetTransaction()
Specified by:
doGetTransaction in class org.springframework.transaction.support.AbstractPlatformTransactionManager

isExistingTransaction

protected boolean isExistingTransaction(java.lang.Object transaction)
Overrides:
isExistingTransaction in class org.springframework.transaction.support.AbstractPlatformTransactionManager

doBegin

protected void doBegin(java.lang.Object transaction,
                       org.springframework.transaction.TransactionDefinition definition)
This implementation sets the isolation level but ignores the timeout.

Specified by:
doBegin in class org.springframework.transaction.support.AbstractPlatformTransactionManager

doSuspend

protected java.lang.Object doSuspend(java.lang.Object transaction)
Overrides:
doSuspend in class org.springframework.transaction.support.AbstractPlatformTransactionManager

doResume

protected void doResume(java.lang.Object transaction,
                        java.lang.Object suspendedResources)
Overrides:
doResume in class org.springframework.transaction.support.AbstractPlatformTransactionManager

doCommit

protected void doCommit(org.springframework.transaction.support.DefaultTransactionStatus status)
Specified by:
doCommit in class org.springframework.transaction.support.AbstractPlatformTransactionManager

doRollback

protected void doRollback(org.springframework.transaction.support.DefaultTransactionStatus status)
Specified by:
doRollback in class org.springframework.transaction.support.AbstractPlatformTransactionManager

doSetRollbackOnly

protected void doSetRollbackOnly(org.springframework.transaction.support.DefaultTransactionStatus status)
Overrides:
doSetRollbackOnly in class org.springframework.transaction.support.AbstractPlatformTransactionManager

doCleanupAfterCompletion

protected void doCleanupAfterCompletion(java.lang.Object transaction)
Overrides:
doCleanupAfterCompletion in class org.springframework.transaction.support.AbstractPlatformTransactionManager

spring-jdbc