Что такое правильный способ обработки соединений JDBC с помощью Spring и DBCP?

Я использую Spring MVC для создания тонкого слоя поверх базы данных SQL Server. Когда я начал тестирование, кажется, что он не очень хорошо справляется со стрессом :). Я использую Apache Commons DBCP для обработки пула соединений и источника данных.

Когда я впервые попробовал ~ 10-15 одновременных подключений, он зависал, и мне приходилось перезагружать сервер (для разработчика я использую Tomcat, но в конечном итоге мне придется развернуться на Weblogic).

Это мои определения bean-компонентов Spring:


    
    
    
    



    



И вот как я их использую:

// in the DAO
public JdbcPartnerDAO(DataSource dataSource) {
    jdbcTemplate = new JdbcTemplate(dataSource);
}

// in the controller
@Autowired
private PartnerDAO partnerDAO;

// in the controller method
Collection partners = partnerDAO.getPartners(...);

Прочитав немного, я нашел maxWait , Свойства maxActive и maxIdle для BasicDataSource (из GenericObjectPool ). Здесь возникает проблема. Я не уверен, как я должен установить их, с точки зрения производительности. Насколько я знаю, Spring должен управлять моими соединениями, поэтому мне не нужно беспокоиться об их освобождении.


    
    
    
    
    
    
    

Во-первых, я установил maxWait , чтобы он не зависал, а вместо этого выбрасывал исключение, когда в пуле не было доступного соединения. Сообщение об исключении было:

Не удалось получить соединение JDBC; Вложенное исключение - org.apache.commons.dbcp.SQLNestedException: не удается получить соединение, ошибка пула Тайм-аут ожидания незанятого объекта

Есть несколько длительных запросов, но исключение было выдано независимо от сложности запроса.

Затем, Я установил maxActive и maxIdle, чтобы он не выдавал исключения в первую очередь. Значения по умолчанию: 8 для maxActive и maxIdle (я не понимаю, почему); если я установлю их в -1, больше не будет выдаваться исключений, и все , похоже, будет работать нормально.

Учитывая, что это приложение должно поддерживать большое количество одновременных запросов, можно ли оставить эти настройки бесконечными ? Будет ли Spring фактически управлять моими соединениями, учитывая ошибки, которые я получал? Должен ли я переключиться на C3P0 , учитывая, что он вроде мертв?

7
задан Seb 25 January 2016 в 11:59
поделиться

2 ответа

Как вы уже выяснили, пул соединений dbcp по умолчанию составляет 8 соединений, поэтому если вы хотите выполнить 9 одновременных запросов, один из них будет заблокирован. Я предлагаю вам подключиться к вашей базе данных и выполнить exec sp_who2, который покажет вам, что подключено и активно, и блокируются ли какие-либо запросы. После этого вы сможете определить, где проблема - в базе данных или в вашем коде.

Пока вы используете семейство объектов Spring JdbcTemplate, ваши соединения будут управляться так, как вы ожидаете, и если вы хотите использовать необработанный источник данных, убедитесь, что вы используете DataSourceUtils для получения соединения.

Еще одно предложение - до Spring 3 никогда не используйте JdbcTemplate, придерживайтесь SimpleJdbcTemplate, вы все еще можете получить доступ к тем же методам, используя SimpleJdbcTemplate.getJdbcOperations(), но вы обнаружите, что пишете гораздо более приятный код, используя generics, и устраните необходимость создавать экземпляры JdbcTemplate/NamedParameterJdbcTemplate.

6
ответ дан 6 December 2019 в 11:45
поделиться

Давайте изменим перспективу.

но исключение было выброшено независимо от сложности запроса

Это может быть связано с тем, что таблица или записи в таблице, к которой вы выполняете запрос, были заблокированы (другой активной транзакцией), и поэтому он затягивается.

Попробуйте выполнить тот же запрос с SQLServer Client, и если это займет много времени, то вы можете быть уверены, что причиной является блокировка таблицы или записи.

2
ответ дан 6 December 2019 в 11:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: