|
|
|
@ -460,48 +460,56 @@ public class LazyConnectionDataSourceProxy extends DelegatingDataSource { |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Return the target Connection, fetching it and initializing it if necessary. |
|
|
|
* Return the target Connection, fetching it and initializing it if necessary. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private Connection getTargetConnection(Method operation) throws SQLException { |
|
|
|
private Connection getTargetConnection(Method operation) throws Throwable { |
|
|
|
if (this.target == null) { |
|
|
|
Connection target = this.target; |
|
|
|
// No target Connection held -> fetch one.
|
|
|
|
if (target != null) { |
|
|
|
|
|
|
|
// Target Connection already held -> return it.
|
|
|
|
if (logger.isTraceEnabled()) { |
|
|
|
if (logger.isTraceEnabled()) { |
|
|
|
logger.trace("Connecting to database for operation '" + operation.getName() + "'"); |
|
|
|
logger.trace("Using existing database connection for operation '" + operation.getName() + "'"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return target; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Fetch physical Connection from DataSource.
|
|
|
|
// No target Connection held -> fetch one.
|
|
|
|
DataSource dataSource = getDataSourceToUse(); |
|
|
|
if (logger.isTraceEnabled()) { |
|
|
|
this.target = (this.username != null ? dataSource.getConnection(this.username, this.password) : |
|
|
|
logger.trace("Connecting to database for operation '" + operation.getName() + "'"); |
|
|
|
dataSource.getConnection()); |
|
|
|
} |
|
|
|
if (this.target == null) { |
|
|
|
|
|
|
|
throw new IllegalStateException("DataSource returned null from getConnection(): " + dataSource); |
|
|
|
// Fetch physical Connection from DataSource.
|
|
|
|
} |
|
|
|
DataSource dataSource = getDataSourceToUse(); |
|
|
|
|
|
|
|
target = (this.username != null ? dataSource.getConnection(this.username, this.password) : |
|
|
|
|
|
|
|
dataSource.getConnection()); |
|
|
|
|
|
|
|
if (target == null) { |
|
|
|
|
|
|
|
throw new IllegalStateException("DataSource returned null from getConnection(): " + dataSource); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Apply kept transaction settings, if any.
|
|
|
|
// Apply kept transaction settings, if any.
|
|
|
|
|
|
|
|
try { |
|
|
|
if (this.readOnly && readOnlyDataSource == null) { |
|
|
|
if (this.readOnly && readOnlyDataSource == null) { |
|
|
|
try { |
|
|
|
DataSourceUtils.setReadOnlyIfPossible(target); |
|
|
|
this.target.setReadOnly(true); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (Exception ex) { |
|
|
|
|
|
|
|
// "read-only not supported" -> ignore, it's just a hint anyway
|
|
|
|
|
|
|
|
logger.debug("Could not set JDBC Connection read-only", ex); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
if (this.transactionIsolation != null && |
|
|
|
if (this.transactionIsolation != null && |
|
|
|
!this.transactionIsolation.equals(defaultTransactionIsolation())) { |
|
|
|
!this.transactionIsolation.equals(defaultTransactionIsolation())) { |
|
|
|
this.target.setTransactionIsolation(this.transactionIsolation); |
|
|
|
target.setTransactionIsolation(this.transactionIsolation); |
|
|
|
} |
|
|
|
} |
|
|
|
if (this.autoCommit != null && this.autoCommit != defaultAutoCommit()) { |
|
|
|
if (this.autoCommit != null && this.autoCommit != defaultAutoCommit()) { |
|
|
|
this.target.setAutoCommit(this.autoCommit); |
|
|
|
target.setAutoCommit(this.autoCommit); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
catch (Throwable settingsEx) { |
|
|
|
else { |
|
|
|
logger.debug("Failed to apply transaction settings to JDBC Connection", settingsEx); |
|
|
|
// Target Connection already held -> return it.
|
|
|
|
// Close Connection and do not set it as target.
|
|
|
|
if (logger.isTraceEnabled()) { |
|
|
|
try { |
|
|
|
logger.trace("Using existing database connection for operation '" + operation.getName() + "'"); |
|
|
|
target.close(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (Throwable closeEx) { |
|
|
|
|
|
|
|
logger.debug("Could not close JDBC Connection after failed settings", closeEx); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
throw settingsEx; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return this.target; |
|
|
|
this.target = target; |
|
|
|
|
|
|
|
return target; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private DataSource getDataSourceToUse() { |
|
|
|
private DataSource getDataSourceToUse() { |
|
|
|
|