org.springframework.jdbc.datasource

## Class TransactionAwareDataSourceProxy

- java.lang.Object
- - org.springframework.jdbc.datasource.DelegatingDataSource
  - - org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy

- All Implemented Interfaces:
    Wrapper, CommonDataSource, DataSource, InitializingBean

      public class TransactionAwareDataSourceProxy
      extends DelegatingDataSource

  Proxy for a target JDBC `DataSource`, adding awareness of Spring-managed transactions. Similar to a transactional JNDI DataSource as provided by a J2EE server.

  Data access code that should remain unaware of Spring's data access support can work with this proxy to seamlessly participate in Spring-managed transactions. Note that the transaction manager, for example `DataSourceTransactionManager`, still needs to work with the underlying DataSource, not with this proxy.

  Make sure that TransactionAwareDataSourceProxy is the outermost DataSource of a chain of DataSource proxies/adapters. TransactionAwareDataSourceProxy can delegate either directly to the target connection pool or to some intermediary proxy/adapter like `LazyConnectionDataSourceProxy` or `UserCredentialsDataSourceAdapter`.

  Delegates to `DataSourceUtils` for automatically participating in thread-bound transactions, for example managed by `DataSourceTransactionManager`. `getConnection` calls and `close` calls on returned Connections will behave properly within a transaction, i.e. always operate on the transactional Connection. If not within a transaction, normal DataSource behavior applies.

  This proxy allows data access code to work with the plain JDBC API and still participate in Spring-managed transactions, similar to JDBC code in a J2EE/JTA environment. However, if possible, use Spring's DataSourceUtils, JdbcTemplate or JDBC operation objects to get transaction participation even without a proxy for the target DataSource, avoiding the need to define such a proxy in the first place.

  As a further effect, using a transaction-aware DataSource will apply remaining transaction timeouts to all created JDBC (Prepared/Callable)Statement. This means that all operations performed through standard JDBC will automatically participate in Spring-managed transaction timeouts.

  NOTE: This DataSource proxy needs to return wrapped Connections (which implement the `ConnectionProxy` interface) in order to handle close calls properly. Therefore, the returned Connections cannot be cast to a native JDBC Connection type like OracleConnection or to a connection pool implementation type. Use a corresponding `NativeJdbcExtractor` to retrieve the native JDBC Connection.

  Since:
    1.1
  Author:
    Juergen Hoeller
  See Also:
    `DataSource.getConnection()`, `Connection.close()`, `DataSourceUtils.doGetConnection(javax.sql.DataSource)`, `DataSourceUtils.applyTransactionTimeout(java.sql.Statement, javax.sql.DataSource)`, `DataSourceUtils.doReleaseConnection(java.sql.Connection, javax.sql.DataSource)`

- - ### Constructor Summary

    Constructors
    Constructor and Description
    `TransactionAwareDataSourceProxy()` Create a new TransactionAwareDataSourceProxy.
    `TransactionAwareDataSourceProxy(DataSource targetDataSource)` Create a new TransactionAwareDataSourceProxy.

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `Connection` | `getConnection()` Delegates to DataSourceUtils for automatically participating in Spring-managed transactions.
    `protected Connection` | `getTransactionAwareConnectionProxy(DataSource targetDataSource)` Wraps the given Connection with a proxy that delegates every method call to it but delegates `close()` calls to DataSourceUtils.
    `void` | `setReobtainTransactionalConnections(boolean reobtainTransactionalConnections)` Specify whether to reobtain the target Connection for each operation performed within a transaction.
    `protected boolean` | `shouldObtainFixedConnection(DataSource targetDataSource)` Determine whether to obtain a fixed target Connection for the proxy or to reobtain the target Connection for each operation.

    - ### Methods inherited from class org.springframework.jdbc.datasource.DelegatingDataSource

      `afterPropertiesSet, getConnection, getLoginTimeout, getLogWriter, getParentLogger, getTargetDataSource, isWrapperFor, setLoginTimeout, setLogWriter, setTargetDataSource, unwrap`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Constructor Detail

    - #### TransactionAwareDataSourceProxy

          public TransactionAwareDataSourceProxy()

      Create a new TransactionAwareDataSourceProxy.
      See Also:
        `DelegatingDataSource.setTargetDataSource(javax.sql.DataSource)`

    - #### TransactionAwareDataSourceProxy

          public TransactionAwareDataSourceProxy(DataSource targetDataSource)

      Create a new TransactionAwareDataSourceProxy.
      Parameters:
        `targetDataSource` - the target DataSource

  - ### Method Detail

    - #### setReobtainTransactionalConnections

          public void setReobtainTransactionalConnections(boolean reobtainTransactionalConnections)

      Specify whether to reobtain the target Connection for each operation performed within a transaction.

      The default is "false". Specify "true" to reobtain transactional Connections for every call on the Connection proxy; this is advisable on JBoss if you hold on to a Connection handle across transaction boundaries.

      The effect of this setting is similar to the "hibernate.connection.release_mode" value "after_statement".

    - #### getConnection

          public Connection getConnection()
                                   throws SQLException

      Delegates to DataSourceUtils for automatically participating in Spring-managed transactions. Throws the original SQLException, if any.

      The returned Connection handle implements the ConnectionProxy interface, allowing to retrieve the underlying target Connection.

      Specified by:
        `getConnection` in interface `DataSource`
      Overrides:
        `getConnection` in class `DelegatingDataSource`
      Returns:
        a transactional Connection if any, a new one else
      Throws:
        `SQLException`
      See Also:
        `DataSourceUtils.doGetConnection(javax.sql.DataSource)`, `ConnectionProxy.getTargetConnection()`

    - #### getTransactionAwareConnectionProxy

          protected Connection getTransactionAwareConnectionProxy(DataSource targetDataSource)

      Wraps the given Connection with a proxy that delegates every method call to it but delegates `close()` calls to DataSourceUtils.
      Parameters:
        `targetDataSource` - DataSource that the Connection came from
      Returns:
        the wrapped Connection
      See Also:
        `Connection.close()`, `DataSourceUtils.doReleaseConnection(java.sql.Connection, javax.sql.DataSource)`

    - #### shouldObtainFixedConnection

          protected boolean shouldObtainFixedConnection(DataSource targetDataSource)

      Determine whether to obtain a fixed target Connection for the proxy or to reobtain the target Connection for each operation.

      The default implementation returns `true` for all standard cases. This can be overridden through the `"reobtainTransactionalConnections"` flag, which enforces a non-fixed target Connection within an active transaction. Note that non-transactional access will always use a fixed Connection.

      Parameters:
        `targetDataSource` - the target DataSource