Одним словом, Spring JDBCTemplate DriverManagerDataSource
не поддерживает пул соединений. Если вы хотите использовать пул соединений, то DBCP
и C3P0
- хороший выбор.
Давайте рассмотрим исходный код JDBCTemplate , чтобы понять, почему ...
Независимо от вызова update
, queryForObject
и других методов, в конечном итоге они вызовут execute
метод:
@Override
public <T> T execute(ConnectionCallback<T> action) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
Connection con = DataSourceUtils.getConnection(getDataSource());
try {
Connection conToUse = con;
if (this.nativeJdbcExtractor != null) {
// Extract native JDBC Connection, castable to OracleConnection or the like.
conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
}
else {
// Create close-suppressing Connection proxy, also preparing returned Statements.
conToUse = createConnectionProxy(con);
}
return action.doInConnection(conToUse);
}
catch (SQLException ex) {
// Release Connection early, to avoid potential connection pool deadlock
// in the case when the exception translator hasn't been initialized yet.
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw getExceptionTranslator().translate("ConnectionCallback", getSql(action), ex);
}
finally {
DataSourceUtils.releaseConnection(con, getDataSource());
}
}
Он вызывает DataSourceUtils.getConnection
метод для получения соединения и DataSourceUtils.releaseConnection
для разрыва соединения.
Из DataSourceUtils исходного кода мы видим Connection con = dataSource.getConnection();
и con.close();
.
Это означает, что операция получения соединения определяется реализацией интерфейса DataSource , а операция закрытия соединения определяется реализацией интерфейса Соединение . Это позволяет другим реализациям DataSource
/ Connection
легко внедрять Spring JDBCTemplate.
Реализация DataSource
в Spring JDBCTemplate - DriverManagerDataSource . От:
protected Connection getConnectionFromDriverManager(String url, Properties props) throws SQLException {
return DriverManager.getConnection(url, props);
}
И
public static void doCloseConnection(Connection con, DataSource dataSource) throws SQLException {
if (!(dataSource instanceof SmartDataSource) || ((SmartDataSource) dataSource).shouldClose(con)) {
con.close();
}
}
Мы видим каждый раз, когда он возвращает новое соединение и закрывает текущее соединение. Вот почему он не поддерживает пул соединений.
В то время как в DBCP
реализация DataSource
равна PoolingDataSource , мы видим getConnection()
из пула соединений; реализация Connection
- это PoolableConnection , мы видим, что close()
метод не закрывает соединение, а возвращает соединение с пулом соединений.
Это волшебство!