BasicDataSource с JDBCTemplate не объединяет соединения, как ожидалось

Я пытаюсь использовать BasicDataSource для объединения соединений с JDBCTemplate в весеннем приложении. Из всего, что я читал, это должно быть очень просто: просто настройте BasicDataSource в XML, внедрите источник данных в bean-компонент и в методе установки создайте новый JDBCTemplate.

Когда я сделал это, я заметил, что мое выступление было ужасным. Затем я переключился на Spring SingleConnectionDataSource, просто чтобы посмотреть, что произойдет, и моя производительность стала намного лучше. Я начал исследовать с помощью инструмента профилирования и заметил, что при использовании BasicDataSource для каждого запроса создается новое соединение.

Продолжая расследование, я вижу, где соединение закрывается после завершения запроса. В частности, в классе Spring DataSourceUtil:

public static void doReleaseConnection(Connection con, DataSource dataSource) throws SQLException {
    if (con == null) {
        return;
    }

    if (dataSource != null) {
        ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
        if (conHolder != null && connectionEquals(conHolder, con)) {
            // It's the transactional Connection: Don't close it.
            conHolder.released();
            return;
        }
    }

    // Leave the Connection open only if the DataSource is our
    // special SmartDataSoruce and it wants the Connection left open.
    if (!(dataSource instanceof SmartDataSource) || ((SmartDataSource) dataSource).shouldClose(con)) {
        logger.debug("Returning JDBC Connection to DataSource");
        con.close();
    }
}

Я заметил, что для «SmartDataSource» существует некоторая особая логика, которая оставляет соединение открытым. Это частично объясняет поведение, которое я наблюдал: поскольку SingleConnectionDataSource реализует SmartDataSource, соединение не закрывается. Однако я думал, что при использовании BasicDataSource метод close() для соединения просто вернет соединение с пулом. Однако, когда я смотрю на то, что происходит в моем профилировщике, метод close на самом деле вызывается для моего соединения с sybase, а не для какой-либо «обертки объединенного соединения», как я ожидал увидеть.

И последнее (это то, что я собираюсь исследовать сейчас): я использую TransactionTemplate для некоторых моих запросов (включая фиксации в базе данных), но простые запросы не находятся внутри transactionTemplate. Не знаю, связано это с проблемой или нет.

РЕДАКТИРОВАТЬ 1:

Хорошо, наконец-то появилось еще немного времени для расследования после того, как проект немного оторвался, и вот очень простой тест, который показывает проблему.

    public class DBConnectionPoolTest {

@Autowired
@Qualifier("myDataSource")
private DataSource dataSource;

@Test
public void test() throws Exception{
    JdbcTemplate template = new JdbcTemplate(dataSource);
    StopWatch sw = new StopWatch();
    sw.start();
    for(int i=0; i<1000; i++){
        template.queryForInt("select count(*) from mytable"); 
    }
    sw.stop();

    System.out.println("TIME: " + sw.getTotalTimeSeconds() + " seconds");   
}}

Вот мои две конфигурации источника данных:

<bean id="myDataSource" class="org.springframework.jdbc.datasource.SingleConnectionDataSource">
    <property name="driverClassName" value="${db.driver}" />
    <property name="url" value="${db.url}" />
    <property name="username" value="${db.username}" />
    <property name="password" value="${db.password}" />
</bean>

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="${db.driver}" />
    <property name="url" value="${db.url}" />
    <property name="username" value="${db.username}" />
    <property name="password" value="${db.password}" />
</bean>

Когда я запускаю тест с первой конфигурацией, это занимает около 2,1 секунды. Когда я запускаю его со второй конфигурацией, это занимает около 4,5 секунд. Я пробовал различные параметры в BasicDataSource, такие как установка maxActive=1 и testOnBorrow=false, но ничего не изменилось.


person Kyle    schedule 20.03.2012    source источник
comment
Покажите нам свою конфигурацию, где вы настраиваете и вводите источник данных и JdbcTemplate.   -  person skaffman    schedule 20.03.2012


Ответы (1)


Думаю, проблема в моем случае заключалась в том, что мои библиотеки jdbc для sybase устарели.

person Kyle    schedule 01.04.2013