Qual é a maneira correta de lidar com conexões JDBC com Spring e DBCP?
Estou usando o Spring MVC para criar uma camada fina em cima de um banco de dados do SQL Server. Quando comecei a testar, parece que ele não lida muito bem com o estresse :). estou a usarApache Commons DBCP para lidar com o pool de conexões e a fonte de dados.
Quando tentei ~ 10-15 conexões simultâneas, ele travou e eu teria que reiniciar o servidor (para dev, estou usando o Tomcat, mas terei que implantar no Weblogic eventualmente).
Estas são minhas definições de bean Spring:
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="url" value="[...]"/>
<property name="username" value="[...]" />
<property name="password" value="[...]" />
</bean>
<bean id="partnerDAO" class="com.hp.gpl.JdbcPartnerDAO">
<constructor-arg ref="dataSource"/>
</bean>
<!-- + other beans -->
E é assim que eu os uso:
// in the DAO
public JdbcPartnerDAO(DataSource dataSource) {
jdbcTemplate = new JdbcTemplate(dataSource);
}
// in the controller
@Autowired
private PartnerDAO partnerDAO;
// in the controller method
Collection<Partner> partners = partnerDAO.getPartners(...);
Depois de ler um pouco, encontrei omaxWait
, maxActive
emaxIdle
propriedades para oBasicDataSource (porGenericObjectPool) Aí vem o problema. Não tenho certeza de como devo defini-los, em termos de desempenho. Pelo que sei, o Spring deve gerenciar minhas conexões, para que não precise me preocupar em liberá-las.
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="url" value="[...]"/>
<property name="username" value="[...]" />
<property name="password" value="[...]" />
<property name="maxWait" value="30" />
<property name="maxIdle" value="-1" />
<property name="maxActive" value="-1" />
</bean>
Primeiro, eu definomaxWait
, para não travar e, em vez disso, lançar uma exceção quando nenhuma conexão estava disponível no pool. A mensagem de exceção foi:
Não foi possível obter a conexão JDBC; exceção aninhada é org.apache.commons.dbcp.SQLNestedException: Não é possível obter uma conexão, erro de pool Tempo limite aguardando pelo objeto inativo
Existem algumas consultas de longa execução, mas a exceção foi lançada independentemente da complexidade da consulta.
Em seguida, defino maxActive e maxIdle para não lançar as exceções em primeiro lugar. Os valores padrão são 8 paramaxActive
emaxIdle
(Eu não entendo o porquê); se eu configurá-los para -1, não há mais exceções lançadas e tudoparece funcionar bem.
Considerando que este aplicativo deve suportar um grande número de solicitações simultâneas, é permitido deixar essas configurações infinitas? O Spring realmente gerenciará minhas conexões, considerando os erros que eu estava recebendo? Devo mudar paraC3P0 considerando que está meio morto?