Application code is required to retrieve the JDBC Connection via
DataSourceUtils.getConnection(DataSource) instead of J2EE's standard
DataSource.getConnection(). This is recommended anyway, as it throws
unchecked org.springframework.dao exceptions instead of checked SQLException.
All framework classes like JdbcTemplate use this strategy implicitly.
If not used with this transaction manager, the lookup strategy behaves exactly
like the common one - it can thus be used in any case.
Alternatively, you can also allow application code to work with the standard
J2EE 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 through it. Note that DataSourceTransactionManager still needs to
be wired with the target DataSource, driving transactions for it.
Supports custom isolation levels, and timeouts that get applied as
appropriate JDBC statement timeouts. To support the latter, application code
must either use JdbcTemplate, call DataSourceUtils.applyTransactionTimeout
for each created statement, or go through a TransactionAwareDataSourceProxy
which will create timeout-aware Connections and Statements.
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, that is, transactions without any
statements executed. LazyConnectionDataSourceProxy will not fetch a JDBC
Connection from the target DataSource until the first statement execution,
lazily applying the specified transaction settings to the target Conection.
On JDBC 3.0, this transaction manager supports nested transactions via JDBC
3.0 Savepoints. The "nestedTransactionAllowed" flag defaults to true, as nested
transactions work without restrictions on JDBC drivers that support Savepoints
(such as the Oracle JDBC driver).
This implementation can be used as a replacement for 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, if you stick to the required connection lookup
pattern. Note that JTA does not support custom isolation levels!