Top Description Inners Fields Constructors Methods
org.springframework.jdbc.datasource

public Class LazyConnectionDataSourceProxy

extends DelegatingDataSource
Class Inheritance
Imports
java.lang.reflect.InvocationHandler, .InvocationTargetException, .Method, .Proxy, java.sql.Connection, .ResultSet, .SQLException, java.util.Map, javax.sql.DataSource, org.apache.commons.logging.Log, .LogFactory, org.springframework.lang.Nullable, org.springframework.util.Assert

Proxy for a target DataSource, fetching actual JDBC Connections lazily, i.e. not until first creation of a Statement. Connection initialization properties like auto-commit mode, transaction isolation and read-only mode will be kept and applied to the actual JDBC Connection as soon as an actual Connection is fetched (if ever). Consequently, commit and rollback calls will be ignored if no Statements have been created. As of 6.1.2, there is also special support for a read-only DataSource to use during a read-only transaction, in addition to the regular target DataSource.

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. As a bonus, this allows for taking the transaction-synchronized read-only flag and/or isolation level into account in a routing DataSource (e.g. org.springframework.jdbc.datasource.lookup.IsolationLevelDataSourceRouter).

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. As of 6.1.2, LazyConnectionDataSourceProxy will initialize its default connection characteristics on first Connection access; to enforce this on startup, call checkDefaultConnectionProperties().

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 Jakarta 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 Connection#unwrap to retrieve the native JDBC Connection.

Authors
Juergen Hoeller, Sam Brannen
Since
1.1.4
See Also
DataSourceTransactionManager, setTargetDataSource, setReadOnlyDataSource

Nested and Inner Type Summary

Modifier and TypeClass and Description
private class
LazyConnectionDataSourceProxy.LazyConnectionInvocationHandler

Invocation handler that defers fetching an actual JDBC Connection until first creation of a Statement.

Field Summary

Modifier and TypeField and Description
pack-priv static final Map<String, Integer>
constants

Map of constant names to constant values for the isolation constants defined in java.sql.Connection.

private volatile Boolean
private volatile Integer
private static final Log
private DataSource

Constructor Summary

AccessConstructor and Description
public
LazyConnectionDataSourceProxy()

Create a new LazyConnectionDataSourceProxy.

public
LazyConnectionDataSourceProxy(DataSource
the target DataSource
targetDataSource
)

Create a new LazyConnectionDataSourceProxy.

Method Summary

Modifier and TypeMethod and Description
public void
checkDefaultConnectionProperties()

Determine default auto-commit and transaction isolation via a Connection from the target DataSource, if possible.

protected void
checkDefaultConnectionProperties(Connection
the Connection to use for checking
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 later on.

protected Boolean
defaultAutoCommit()

Expose the default auto-commit value.

protected Integer
defaultTransactionIsolation()

Expose the default transaction isolation value.

public Connection

Returns:

a lazy Connection handle
getConnection
()

Overrides org.springframework.jdbc.datasource.DelegatingDataSource.getConnection.

Implements javax.sql.DataSource.getConnection.

Return a Connection handle that lazily fetches an actual JDBC Connection when asked for a Statement (or PreparedStatement or CallableStatement).

public Connection

Returns:

a lazy Connection handle
getConnection
(String
the per-Connection username
username
,
String
the per-Connection password
password
)

Overrides org.springframework.jdbc.datasource.DelegatingDataSource.getConnection.

Implements javax.sql.DataSource.getConnection.

Return a Connection handle that lazily fetches an actual JDBC Connection when asked for a Statement (or PreparedStatement or CallableStatement).

public void
setDefaultAutoCommit(boolean defaultAutoCommit)

Set the default auto-commit mode to expose when no target Connection has been fetched yet (when the actual JDBC Connection default is not known yet).

public void
setDefaultTransactionIsolation(int defaultTransactionIsolation)

Set the default transaction isolation level to expose when no target Connection has been fetched yet (when the actual JDBC Connection default is not known yet).

public void
setDefaultTransactionIsolationName(String
name of the constant
constantName
)

Set the default transaction isolation level by the name of the corresponding constant in java.sql.Connection — for example, "TRANSACTION_SERIALIZABLE".

public void
setReadOnlyDataSource(DataSource readOnlyDataSource)

Specify a variant of the target DataSource to use for read-only transactions.

Inherited from org.springframework.jdbc.datasource.DelegatingDataSource:
afterPropertiesSetcreateConnectionBuildercreateShardingKeyBuildergetLoginTimeoutgetLogWritergetParentLoggergetTargetDataSourceisWrapperForobtainTargetDataSourcesetLoginTimeoutsetLogWritersetTargetDataSourceunwrap

Field Detail

constantsback to summary
pack-priv static final Map<String, Integer> constants

Map of constant names to constant values for the isolation constants defined in java.sql.Connection.

defaultAutoCommitback to summary
private volatile Boolean defaultAutoCommit
Annotations
@Nullable
defaultTransactionIsolationback to summary
private volatile Integer defaultTransactionIsolation
Annotations
@Nullable
loggerback to summary
private static final Log logger
readOnlyDataSourceback to summary
private DataSource readOnlyDataSource
Annotations
@Nullable

Constructor Detail

LazyConnectionDataSourceProxyback to summary
public LazyConnectionDataSourceProxy()

Create a new LazyConnectionDataSourceProxy.

See Also
setTargetDataSource, setReadOnlyDataSource
LazyConnectionDataSourceProxyback to summary
public LazyConnectionDataSourceProxy(DataSource targetDataSource)

Create a new LazyConnectionDataSourceProxy.

Parameters
targetDataSource:DataSource

the target DataSource

See Also
setTargetDataSource

Method Detail

checkDefaultConnectionPropertiesback to summary
public void checkDefaultConnectionProperties()

Determine default auto-commit and transaction isolation via a Connection from the target DataSource, if possible.

Since
6.1.2
See Also
checkDefaultConnectionProperties(Connection)
checkDefaultConnectionPropertiesback to summary
protected void checkDefaultConnectionProperties(Connection con) throws SQLException

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 later on.

Parameters
con:Connection

the Connection to use for checking

Exceptions
SQLException:
if thrown by Connection methods
defaultAutoCommitback to summary
protected Boolean defaultAutoCommit()

Expose the default auto-commit value.

Annotations
@Nullable
defaultTransactionIsolationback to summary
protected Integer defaultTransactionIsolation()

Expose the default transaction isolation value.

Annotations
@Nullable
getConnectionback to summary
public Connection getConnection() throws SQLException

Overrides org.springframework.jdbc.datasource.DelegatingDataSource.getConnection.

Implements javax.sql.DataSource.getConnection.

Return a Connection handle that lazily fetches an actual JDBC Connection when asked for a Statement (or PreparedStatement or CallableStatement).

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

Returns:Connection

a lazy Connection handle

Annotations
@Override
Exceptions
SQLException:

Doc from javax.sql.DataSource.getConnection.

if a database access error occurs

See Also
ConnectionProxy#getTargetConnection()
getConnectionback to summary
public Connection getConnection(String username, String password) throws SQLException

Overrides org.springframework.jdbc.datasource.DelegatingDataSource.getConnection.

Implements javax.sql.DataSource.getConnection.

Return a Connection handle that lazily fetches an actual JDBC Connection when asked for a Statement (or PreparedStatement or CallableStatement).

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

Parameters
username:String

the per-Connection username

password:String

the per-Connection password

Returns:Connection

a lazy Connection handle

Annotations
@Override
Exceptions
SQLException:

Doc from javax.sql.DataSource.getConnection.

if a database access error occurs

See Also
ConnectionProxy#getTargetConnection()
setDefaultAutoCommitback to summary
public void setDefaultAutoCommit(boolean defaultAutoCommit)

Set the default auto-commit mode to expose when no target Connection has been fetched yet (when the actual JDBC Connection default is not known yet).

If not specified, the default gets determined by checking lazily on first access of a Connection.

See Also
java.sql.Connection#setAutoCommit
setDefaultTransactionIsolationback to summary
public void setDefaultTransactionIsolation(int defaultTransactionIsolation)

Set the default transaction isolation level to expose when no target Connection has been fetched yet (when the actual JDBC Connection default is not known yet).

This property accepts the int constant value (e.g. 8) as defined in the java.sql.Connection interface; it is mainly intended for programmatic use. Consider using the "defaultTransactionIsolationName" property for setting the value by name (for example, "TRANSACTION_SERIALIZABLE").

If not specified, the default gets determined by checking lazily on first access of a Connection.

See Also
setDefaultTransactionIsolationName, java.sql.Connection#setTransactionIsolation
setDefaultTransactionIsolationNameback to summary
public void setDefaultTransactionIsolationName(String constantName)

Set the default transaction isolation level by the name of the corresponding constant in java.sql.Connection — for example, "TRANSACTION_SERIALIZABLE".

Parameters
constantName:String

name of the constant

See Also
setDefaultTransactionIsolation, java.sql.Connection#TRANSACTION_READ_UNCOMMITTED, java.sql.Connection#TRANSACTION_READ_COMMITTED, java.sql.Connection#TRANSACTION_REPEATABLE_READ, java.sql.Connection#TRANSACTION_SERIALIZABLE
setReadOnlyDataSourceback to summary
public void setReadOnlyDataSource(DataSource readOnlyDataSource)

Specify a variant of the target DataSource to use for read-only transactions.

If available, a Connection from such a read-only DataSource will be lazily obtained within a Spring-managed transaction that has been marked as read-only. The Connection#setReadOnly flag will be left untouched, expecting it to be pre-configured as a default on the read-only DataSource, avoiding the overhead of switching it at the beginning and end of every transaction. Also, the default auto-commit and isolation level settings are expected to match the default connection properties of the primary target DataSource.

Since
6.1.2
See Also
setTargetDataSource, setDefaultAutoCommit, setDefaultTransactionIsolation, org.springframework.transaction.TransactionDefinition#isReadOnly()
org.springframework.jdbc.datasource back to summary

private Class LazyConnectionDataSourceProxy.LazyConnectionInvocationHandler

extends Object
implements InvocationHandler
Class Inheritance
  • java.lang.Object
  • org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy.LazyConnectionInvocationHandler
All Implemented Interfaces
java.lang.reflect.InvocationHandler

Invocation handler that defers fetching an actual JDBC Connection until first creation of a Statement.

Field Summary

Modifier and TypeField and Description
private Boolean
private boolean
private int
private String
private boolean
private Connection
private Integer
private String

Constructor Summary

AccessConstructor and Description
public
public

Method Summary

Modifier and TypeMethod and Description
private DataSource
private Connection
getTargetConnection(Method operation)

Return the target Connection, fetching it and initializing it if necessary.

private boolean
hasTargetConnection()

Return whether the proxy currently holds a target Connection.

public Object
invoke(Object
the proxy instance that the method was invoked on
proxy
,
Method
the Method instance corresponding to the interface method invoked on the proxy instance. The declaring class of the Method object will be the interface that the method was declared in, which may be a superinterface of the proxy interface that the proxy class inherits the method through.
method
,
Object[]
an array of objects containing the values of the arguments passed in the method invocation on the proxy instance, or null if interface method takes no arguments. Arguments of primitive types are wrapped in instances of the appropriate primitive wrapper class, such as java.lang.Integer or java.lang.Boolean.
args
)

Implements java.lang.reflect.InvocationHandler.invoke.

Processes a method invocation on a proxy instance and returns the result.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

autoCommitback to summary
private Boolean autoCommit
Annotations
@Nullable
closedback to summary
private boolean closed
holdabilityback to summary
private int holdability
passwordback to summary
private String password
Annotations
@Nullable
readOnlyback to summary
private boolean readOnly
targetback to summary
private Connection target
Annotations
@Nullable
transactionIsolationback to summary
private Integer transactionIsolation
Annotations
@Nullable
usernameback to summary
private String username
Annotations
@Nullable

Constructor Detail

LazyConnectionInvocationHandlerback to summary
public LazyConnectionInvocationHandler()
LazyConnectionInvocationHandlerback to summary
public LazyConnectionInvocationHandler(String username, String password)

Method Detail

getDataSourceToUseback to summary
private DataSource getDataSourceToUse()
getTargetConnectionback to summary
private Connection getTargetConnection(Method operation) throws SQLException

Return the target Connection, fetching it and initializing it if necessary.

hasTargetConnectionback to summary
private boolean hasTargetConnection()

Return whether the proxy currently holds a target Connection.

invokeback to summary
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable

Implements java.lang.reflect.InvocationHandler.invoke.

Doc from java.lang.reflect.InvocationHandler.invoke.

Processes a method invocation on a proxy instance and returns the result. This method will be invoked on an invocation handler when a method is invoked on a proxy instance that it is associated with.

Parameters
proxy:Object

the proxy instance that the method was invoked on

method:Method

the Method instance corresponding to the interface method invoked on the proxy instance. The declaring class of the Method object will be the interface that the method was declared in, which may be a superinterface of the proxy interface that the proxy class inherits the method through.

args:Object[]

an array of objects containing the values of the arguments passed in the method invocation on the proxy instance, or null if interface method takes no arguments. Arguments of primitive types are wrapped in instances of the appropriate primitive wrapper class, such as java.lang.Integer or java.lang.Boolean.

Returns:Object

the value to return from the method invocation on the proxy instance. If the declared return type of the interface method is a primitive type, then the value returned by this method must be an instance of the corresponding primitive wrapper class; otherwise, it must be a type assignable to the declared return type. If the value returned by this method is null and the interface method's return type is primitive, then a NullPointerException will be thrown by the method invocation on the proxy instance. If the value returned by this method is otherwise not compatible with the interface method's declared return type as described above, a ClassCastException will be thrown by the method invocation on the proxy instance.

Annotations
@Override
@Nullable
Exceptions
Throwable:
the exception to throw from the method invocation on the proxy instance. The exception's type must be assignable either to any of the exception types declared in the throws clause of the interface method or to the unchecked exception types java.lang.RuntimeException or java.lang.Error. If a checked exception is thrown by this method that is not assignable to any of the exception types declared in the throws clause of the interface method, then an UndeclaredThrowableException containing the exception that was thrown by this method will be thrown by the method invocation on the proxy instance.