public class LazyConnectionDataSourceProxy extends DelegatingDataSource
This DataSource proxy allows to avoid fetching JDBC Connections from a pool unless actually necessary. JDBC transaction control can happen without fetching a Connection from the pool or communicating with the database; this will be done lazily on first creation of a JDBC Statement.
If you configure both a LazyConnectionDataSourceProxy and a TransactionAwareDataSourceProxy, make sure that the latter is the outermost DataSource. In such a scenario, data access code will talk to the transaction-aware DataSource, which will in turn work with the LazyConnectionDataSourceProxy.
Lazy fetching of physical JDBC Connections is particularly beneficial in a generic transaction demarcation environment. It allows you to demarcate transactions on all methods that could potentially perform data access, without paying a performance penalty if no actual data access happens.
This DataSource proxy gives you behavior analogous to JTA and a transactional JNDI DataSource (as provided by the Java EE server), even with a local transaction strategy like DataSourceTransactionManager or HibernateTransactionManager. It does not add value with Spring's JtaTransactionManager as transaction strategy.
Lazy fetching of JDBC Connections is also recommended for read-only operations with Hibernate, in particular if the chances of resolving the result in the second-level cache are high. This avoids the need to communicate with the database at all for such read-only operations. You will get the same effect with non-transactional reads, but lazy fetching of JDBC Connections allows you to still perform reads in transactions.
NOTE: This DataSource proxy needs to return wrapped Connections
(which implement the ConnectionProxy
interface) in order to handle
lazy fetching of an actual JDBC Connection. Use Wrapper.unwrap(java.lang.Class<T>)
to retrieve the native JDBC Connection.
DataSourceTransactionManager
Constructor and Description |
---|
LazyConnectionDataSourceProxy()
Create a new LazyConnectionDataSourceProxy.
|
LazyConnectionDataSourceProxy(javax.sql.DataSource targetDataSource)
Create a new LazyConnectionDataSourceProxy.
|
Modifier and Type | Method and Description |
---|---|
void |
afterPropertiesSet()
Invoked by the containing
BeanFactory after it has set all bean properties
and satisfied BeanFactoryAware , ApplicationContextAware etc. |
protected void |
checkDefaultConnectionProperties(java.sql.Connection con)
Check the default connection properties (auto-commit, transaction isolation),
keeping them to be able to expose them correctly without fetching an actual
JDBC Connection from the target DataSource.
|
protected java.lang.Boolean |
defaultAutoCommit()
Expose the default auto-commit value.
|
protected java.lang.Integer |
defaultTransactionIsolation()
Expose the default transaction isolation value.
|
java.sql.Connection |
getConnection()
Return a Connection handle that lazily fetches an actual JDBC Connection
when asked for a Statement (or PreparedStatement or CallableStatement).
|
java.sql.Connection |
getConnection(java.lang.String username,
java.lang.String password)
Return a Connection handle that lazily fetches an actual JDBC Connection
when asked for a Statement (or PreparedStatement or CallableStatement).
|
void |
setDefaultAutoCommit(boolean defaultAutoCommit)
Set the default auto-commit mode to expose when no target Connection
has been fetched yet (-> actual JDBC Connection default not known yet).
|
void |
setDefaultTransactionIsolation(int defaultTransactionIsolation)
Set the default transaction isolation level to expose when no target Connection
has been fetched yet (-> actual JDBC Connection default not known yet).
|
void |
setDefaultTransactionIsolationName(java.lang.String constantName)
Set the default transaction isolation level by the name of the corresponding
constant in
Connection , e.g. |
getLoginTimeout, getLogWriter, getParentLogger, getTargetDataSource, isWrapperFor, obtainTargetDataSource, setLoginTimeout, setLogWriter, setTargetDataSource, unwrap
public LazyConnectionDataSourceProxy()
public LazyConnectionDataSourceProxy(javax.sql.DataSource targetDataSource)
targetDataSource
- the target DataSourcepublic void setDefaultAutoCommit(boolean defaultAutoCommit)
If not specified, the default gets determined by checking a target Connection on startup. If that check fails, the default will be determined lazily on first access of a Connection.
Connection.setAutoCommit(boolean)
public void setDefaultTransactionIsolation(int defaultTransactionIsolation)
This property accepts the int constant value (e.g. 8) as defined in the
Connection
interface; it is mainly intended for programmatic
use. Consider using the "defaultTransactionIsolationName" property for setting
the value by name (e.g. "TRANSACTION_SERIALIZABLE").
If not specified, the default gets determined by checking a target Connection on startup. If that check fails, the default will be determined lazily on first access of a Connection.
setDefaultTransactionIsolationName(java.lang.String)
,
Connection.setTransactionIsolation(int)
public void setDefaultTransactionIsolationName(java.lang.String constantName)
Connection
, e.g. "TRANSACTION_SERIALIZABLE".constantName
- name of the constantsetDefaultTransactionIsolation(int)
,
Connection.TRANSACTION_READ_UNCOMMITTED
,
Connection.TRANSACTION_READ_COMMITTED
,
Connection.TRANSACTION_REPEATABLE_READ
,
Connection.TRANSACTION_SERIALIZABLE
public void afterPropertiesSet()
InitializingBean
BeanFactory
after it has set all bean properties
and satisfied BeanFactoryAware
, ApplicationContextAware
etc.
This method allows the bean instance to perform validation of its overall configuration and final initialization when all bean properties have been set.
afterPropertiesSet
in interface InitializingBean
afterPropertiesSet
in class DelegatingDataSource
protected void checkDefaultConnectionProperties(java.sql.Connection con) throws java.sql.SQLException
This will be invoked once on startup, but also for each retrieval of a target Connection. If the check failed on startup (because the database was down), we'll lazily retrieve those settings.
con
- the Connection to use for checkingjava.sql.SQLException
- if thrown by Connection methods@Nullable protected java.lang.Boolean defaultAutoCommit()
@Nullable protected java.lang.Integer defaultTransactionIsolation()
public java.sql.Connection getConnection() throws java.sql.SQLException
The returned Connection handle implements the ConnectionProxy interface, allowing to retrieve the underlying target Connection.
getConnection
in interface javax.sql.DataSource
getConnection
in class DelegatingDataSource
java.sql.SQLException
ConnectionProxy.getTargetConnection()
public java.sql.Connection getConnection(java.lang.String username, java.lang.String password) throws java.sql.SQLException
The returned Connection handle implements the ConnectionProxy interface, allowing to retrieve the underlying target Connection.
getConnection
in interface javax.sql.DataSource
getConnection
in class DelegatingDataSource
username
- the per-Connection usernamepassword
- the per-Connection passwordjava.sql.SQLException
ConnectionProxy.getTargetConnection()