Estoy usando Spring MVC para construir una capa delgada sobre una base de datos de SQL Server. Cuando comencé a probar, parece que no maneja el estrés muy bien :). Estoy usando Apache Commons DBCP para manejar la agrupación de conexiones y la fuente de datos.¿Cuál es la forma correcta de manejar las conexiones JDBC con Spring y DBCP?
Cuando intenté por primera vez ~ 10-15 conexiones simultáneas, solía colgar y tenía que reiniciar el servidor (para el desarrollador estoy usando Tomcat, pero voy a tener que implementarlo en Weblogic).
Estos son mis definiciones de frijol de primavera:
<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 -->
y así es como yo los utilizo:
// 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(...);
Después de leer todo un poco, me encontré con los maxWait
, maxActive
y maxIdle
propiedades el BasicDataSource (desde GenericObjectPool). Aquí viene el problema. No estoy seguro de cómo debería configurarlos, en cuanto a rendimiento. Por lo que sé, Spring debería administrar mis conexiones, así que no debería preocuparme por liberarlas.
<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>
En primer lugar, me puse maxWait
, por lo que no sería colgar y en lugar de lanzar una excepción cuando no hay conexión estaba disponible de la piscina. El mensaje de excepción fue:
No se pudo obtener la conexión JDBC; la excepción jerarquizada es org.apache.commons.dbcp.SQLNestedException: No se puede obtener una conexión, error de tiempo de espera de la piscina a la espera de objetos abandonados
Hay algunas consultas de larga ejecución, pero la excepción fue lanzada independientemente de la complejidad de la consulta.
Luego, configuré maxActive y maxIdle para que no arrojara las excepciones en primer lugar. Los valores predeterminados son 8 para maxActive
y maxIdle
(no entiendo por qué); si los configuro en -1 no hay más excepciones lanzadas y todo parece para que funcione bien.
Teniendo en cuenta que esta aplicación debería admitir una gran cantidad de solicitudes simultáneas ¿está bien dejar esta configuración en infinito? ¿Spring realmente administrará mis conexiones, teniendo en cuenta los errores que estaba recibiendo? ¿Debería cambiar a C3P0 teniendo en cuenta que está algo muerto?
Si recibe alguna excepción, publicar la stacktrace ayudará a identificar el problema fácilmente. ¿Hay alguna consulta de larga ejecución en la que vea los problemas? –
He actualizado mi publicación con el mensaje de excepción y alguna información adicional. –