Bonjour,
J'ai web service qui appelle une procédure stockée pour écrire dans une base de données oracle.
Je travaille avec Spring, Apache cxf, pour l'accès base de données, je'utilise l'api jdbc (pas de hibernate)
Pour des besoins de performances, j'ai configuré une pool de connexion avec l'api dbcp d'apache.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
url.datasource=jdbc:oracle:thin:@********:1521:odb
username.datasource=user
password.datasource=password
pool.init.size=10
pool.max.active=30
pool.maxWaitMillis=30000
spring.xml :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
	<context:component-scan base-package="com">
		<context:include-filter type="aspectj" expression="com.service.TracabiliteService"/>
	</context:component-scan>
 
	<context:property-placeholder location="classpath:db.properties"/>
 
	<!-- DAO -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="oracle.jdbc.OracleDriver" />
		<property name="url" value="${url.datasource}" />
		<property name="username" value="${username.datasource}" />
		<property name="password" value="${password.datasource}" />
    	<property name="initialSize" value="${pool.init.size}"/>
    	<property name="maxActive" value="${pool.max.active}"/>
    	<property name="accessToUnderlyingConnectionAllowed" value="true"/>
    	<property name="maxWait" value="${pool.maxWaitMillis}"/>
	</bean>
 
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
 
	<bean id="appInitService" class="com.service.WSGlobalInitializer" init-method="init"></bean>
 
	<!-- AOP -->
	<aop:aspectj-autoproxy/>
Le code appelé par le web service :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
...
		Connection conn = jdbcTemplate.getDataSource().getConnection();
		try {
			Connection dconn = ((DelegatingConnection)conn).getDelegate();
			OracleConnection oconn = dconn.unwrap(OracleConnection.class);
			SimpleJdbcCall sjc = new SimpleJdbcCall(jdbcTemplate).withCatalogName(CATALOGUE)
					.withProcedureName("myProc")
					.declareParameters(new SqlParameter("p_1", OracleTypes.VARCHAR),
							new SqlParameter("p_2", OracleTypes.VARCHAR),
							new SqlParameter("p_liste", OracleTypes.ARRAY, "col"));
			StructDescriptor descType = StructDescriptor.createDescriptor("type", oconn);
			Object[] structListe = prepareTabObjets(objs, descType,	oconn);
 
			ArrayDescriptor descCol = ArrayDescriptor.createDescriptor("col", oconn);
			ARRAY t1 = new ARRAY(descCol, oconn, structListe);
			Map<String, Object> mapParams = new HashMap<String, Object>();
			mapParams.put("p_1", v1);
			mapParams.put("p_2", v2);
			mapParams.put("p_liste", t1);
			Map<String, Object> mapResult = sjc.execute(mapParams);
			...
		} catch (Exception e) {
			logger.error("Erreur", e);
		}finally {
			conn.close();
		}
		...
Mon web service marche très bien. Mais le test de charge avec Jmeter pour un scénario de 50 threads, 1s pour la montée en charge, et 1 pour itération génère des refus.
En vérifiant, je n'ai que 10 réponses. les logs montrent des exceptions de non disponibilité de connexion (saturation de pool de connexion).

1er question : est ce que mon scénario de test est bon, ou il est irréel (50 threads en 1 seconde) ?
2eme question : qu'est ce que je peux faire pour ce problème de saturation de pool de connexion ?

Merci de votre retour