Bonjour,

Je developpe actullement un petite application web destinée à administrer un base de donnée sous postgresql. j'ai utiliser pour ce c3p0 comme gestionnaire de pool de connexion, spring 2 pour l'IOC, et le tout tourne sous tomcat 5.5.17.

Mes classes de la couche DAO sont de la forme :

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
 
package dao.postgresql;
 
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Collection;
import java.util.List;
 
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.RowMapperResultSetExtractor;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
 
import dao.DaoException;
import dao.IDaoAdministrateurs;
import entities.Administrateurs;
 
public class DaoAdministrateurs extends JdbcDaoSupport implements IDaoAdministrateurs {
	public Collection getAllAdministrateurs() {
		JdbcTemplate jt = getJdbcTemplate();
		String sqlquery = "SELECT admin.*, count(DISTINCT ws.ws_url) AS nbr_ws FROM administrateurs AS admin " +
				" LEFT OUTER JOIN websites AS ws ON admin.admin_login = ws.admin_login " +
				" GROUP BY admin.admin_login, admin.admin_password, admin.admin_dtcrea, admin.admin_email, admin.admin_nom, admin.admin_prenom, admin.admin_isadmin" +
				" ORDER BY admin.admin_login, admin.admin_nom, admin.admin_prenom";
		List result = (List) jt.query(sqlquery, new RowMapperResultSetExtractor(new AdministrateurRowMapper()));
		closeConn();
		if(result == null || result.size() == 0) {
			throw new DaoException("Not Found", 1);
		} else {
			return result;
		}
	}
 
 
	public Administrateurs getOneById(String adminLogin) {
		JdbcTemplate jt = getJdbcTemplate();
		String sqlquery = "SELECT admin.*, count(DISTINCT ws.ws_url) AS nbr_ws FROM administrateurs AS admin " +
				" LEFT OUTER JOIN websites AS ws ON admin.admin_login = ws.admin_login " +
				" WHERE admin.admin_login = ? " +
				" GROUP BY admin.admin_login, admin.admin_password, admin.admin_dtcrea, admin.admin_email, admin.admin_nom, admin.admin_prenom, admin.admin_isadmin" +
				" ORDER BY admin.admin_login, admin.admin_nom, admin.admin_prenom";
		Object [] args = new Object [] { adminLogin };
		int [] types = new int [] { Types.VARCHAR };
		try {
			Administrateurs admin = (Administrateurs) jt.queryForObject(sqlquery, args, types, new AdministrateurRowMapper());
			closeConn();
			return admin;
		} catch (Exception e) {
			closeConn();
			throw new DaoException("Not Found", 1);
		}
	}
 
	public Administrateurs getOneByEmail(String adminEmail) {
		JdbcTemplate jt = getJdbcTemplate();
		String sqlquery = "SELECT admin.*, count(DISTINCT ws.ws_url) AS nbr_ws FROM administrateurs AS admin " +
				" LEFT OUTER JOIN websites AS ws ON admin.admin_login = ws.admin_login " +
				" WHERE admin.admin_email = ? " +
				" GROUP BY admin.admin_login, admin.admin_password, admin.admin_dtcrea, admin.admin_email, admin.admin_nom, admin.admin_prenom, admin.admin_isadmin" +
				" ORDER BY admin.admin_login, admin.admin_nom, admin.admin_prenom";
		Object [] args = new Object [] { adminEmail };
		int [] types = new int [] { Types.VARCHAR };
		try {
			Administrateurs admin = (Administrateurs) jt.queryForObject(sqlquery, args, types, new AdministrateurRowMapper());
			closeConn();
			return admin;
		} catch (Exception e) {
			closeConn();
			throw new DaoException("Not Found", 1);
		}
	}
 
	public void saveOne(Administrateurs admin) {
		JdbcTemplate jt = getJdbcTemplate();
		String sqlquery = "INSERT INTO administrateurs (admin_login, admin_password, admin_email, admin_dtcrea, admin_nom, admin_prenom, admin_isadmin) VALUES (?, ?, ?, ?, ?, ?, ?)";
		Object[] args = new Object[7];
		args[0] = admin.getAdminLogin();
		args[1] = admin.getAdminPassword();
		args[2] = admin.getAdminEmail();
		args[3] = admin.getAdminDtcrea();
		if(null != admin.getAdminNom()) {
			args[4] = admin.getAdminNom();
		} else {
			args[4] = null;
		}
		if(null != admin.getAdminPrenom()) {
			args[5] = admin.getAdminPrenom();
		} else {
			args[5] = null;
		}
		args[6] = admin.isAdminIsadmin();
		int [] types = new int [] {Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.TIMESTAMP, Types.VARCHAR, Types.VARCHAR, Types.BOOLEAN};
		try {
			int res = jt.update(sqlquery, args, types);
			closeConn();
			if(res != 1) {
				throw new DaoException("Erreur d'insertion", 2);
			}
		} catch (Exception e) {
			closeConn();
			throw new DaoException("Erreur d'insertion ("+e.getMessage()+")", 2);
		}
	}
 
	public void updateOne(Administrateurs admin) {
		JdbcTemplate jt = getJdbcTemplate();
		String sqlquery = "UPDATE administrateurs SET admin_password = ?, admin_email = ?, admin_dtcrea = ?, admin_nom = ?, admin_prenom = ?, admin_isadmin = ? WHERE admin_login = ?";
		Object[] args = new Object[7];
		args[0] = admin.getAdminPassword();
		args[1] = admin.getAdminEmail();
		args[2] = admin.getAdminDtcrea();
		if(null != admin.getAdminNom()) {
			args[3] = admin.getAdminNom();
		} else {
			args[3] = null;
		}
		if(null != admin.getAdminPrenom()) {
			args[4] = admin.getAdminPrenom();
		} else {
			args[4] = null;
		}
		args[5] = admin.isAdminIsadmin();
		args[6] = admin.getAdminLogin();
		int [] types = new int [] {Types.VARCHAR, Types.VARCHAR, Types.TIMESTAMP, Types.VARCHAR, Types.VARCHAR, Types.BOOLEAN, Types.VARCHAR};
		try {
			int res = jt.update(sqlquery, args, types);
			closeConn();
			if(res != 1) {
				throw new DaoException("Erreur de modification", 3);
			}
		} catch (Exception e) {
			closeConn();
			throw new DaoException("Erreur de modification ("+e.getMessage()+")", 3);
		}
	}
 
	public void deleteOne(Administrateurs admin) {
		JdbcTemplate jt = getJdbcTemplate();
		String sqlquery = "DELETE FROM administrateurs WHERE admin_login = ?";
		Object [] args = new Object [] { admin.getAdminLogin() };
		int [] types = new int [] { Types.VARCHAR };
		try {
			int res = jt.update(sqlquery, args, types);
			closeConn();
			if(res != 1) {
				throw new DaoException("Erreur de suppression", 4);
			}
		} catch (Exception e) {
			closeConn();
			throw new DaoException("Erreur de suppression ("+e.getMessage()+")", 4);
		}
	}
 
	class AdministrateurRowMapper implements RowMapper {
		public Object mapRow(ResultSet rs, int index) throws SQLException {
			Administrateurs admin = new Administrateurs();
			admin.setAdminLogin(rs.getString("admin_login"));
			admin.setAdminPassword(rs.getString("admin_password"));
			admin.setAdminEmail(rs.getString("admin_email"));
			admin.setAdminDtcrea(rs.getTimestamp("admin_dtcrea"));
			admin.setAdminNom(rs.getString("admin_nom"));
			admin.setAdminPrenom(rs.getString("admin_prenom"));
			admin.setAdminIsadmin(rs.getBoolean("admin_isadmin"));
			admin.setNbrWebsites(rs.getInt("nbr_ws"));
			return admin;
		}		
	}
 
	public void closeConn() {
		try {
			getDataSource().getConnection().close();
		} catch (SQLException e) {
			System.err.println(e.getMessage());
		}
	}
}
et je dois avoir une bonne trentaine de classes comme ça.

Mon fichier spring-config.xml est de la forme :

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans SYSTEM "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
	<bean id="myDS" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
		<property name="driverClass">
            <value>org.postgresql.Driver</value>
        </property>
		<property name="jdbcUrl">
<value>jdbc:postgresql://localhost:5432/${dbname}</value>
		</property>
		<property name="acquireIncrement" value="0"/>
		<property name="initialPoolSize" value="1"/>
		<property name="minPoolSize" value="1"/>
		<property name="maxPoolSize" value="2"/>
		<property name="maxIdleTime" value="30"/>
		<property name="maxIdleTimeExcessConnections" value="30"/>
		<property name="idleConnectionTestPeriod" value="30"/>
		<property name="maxStatements" value="0"/>
		<property name="maxStatementsPerConnection" value="0"/>
		<property name="maxConnectionAge" value="40"/>
		<property name="properties">
			<props>
				<prop key="user">${dbuser}</prop>
				<prop key="c3p0.acquireIncrement">0</prop>
				<prop key="c3p0.initialPoolSize">1</prop>
                <prop key="c3p0.minPoolSize">1</prop>
				<prop key="c3p0.maxPoolSize">2</prop>
				<prop key="c3p0.maxIdleTime">30</prop>
				<prop key="c3p0.maxIdleTimeExcessConnections">30</prop>
				<prop key="c3p0.idleConnectionTestPeriod">30</prop>
				<prop key="c3p0.maxStatements">0</prop>
				<prop key="c3p0.maxStatementsPerConnection">0</prop>
				<prop key="c3p0.maxConnectionAge">40</prop>
				<prop key="acquireIncrement">0</prop>
				<prop key="initialPoolSize">1</prop>
                <prop key="minPoolSize">1</prop>
				<prop key="maxPoolSize">2</prop>
				<prop key="maxIdleTime">30</prop>
				<prop key="maxIdleTimeExcessConnections">30</prop>
				<prop key="idleConnectionTestPeriod">30</prop>
				<prop key="maxStatements">0</prop>
				<prop key="maxStatementsPerConnection">0</prop>
				<prop key="maxConnectionAge">40</prop>
                <prop key="password">${dbpass}</prop>
			</props>
		</property>
	</bean>
	<!-- sessionFatory pour JDBC -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource">
			<ref local="myDS"/>
		</property>
	</bean>
	<bean id="AwareTransactionDataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
		<property name="targetDataSource">
			<ref bean="myDS"/>
		</property>
	</bean>
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource">
			<ref bean="AwareTransactionDataSource"/>
		</property>
	</bean>
	<bean id="daoIAdministrateurs" class="dao.postgresql.DaoAdministrateurs">
		<property name="jdbcTemplate">
			<ref bean="jdbcTemplate" />
		</property>
	</bean>
	<bean id="daoAdministrateurs" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
		<property name="transactionManager">
			<ref local="transactionManager"/>
		</property>
		<property name="target">
			<ref local="daoIAdministrateurs"/>
		</property>
		<property name="transactionAttributes">
			<props>
				<prop key="save*">PROPAGATION_REQUIRED</prop>
				<prop key="update*">PROPAGATION_REQUIRED</prop>
				<prop key="del*">PROPAGATION_REQUIRED</prop>
			</props>
		</property>
	</bean>
	<bean id="serviceAdministrateurs" class="services.ServiceAdministrateurs">
		<property name="daoAdministrateurs">
			<ref bean="daoAdministrateurs"/>
		</property>		
	</bean>
 
...
 
</beans>

Mon application fonctionne bien pendant un moment puis commence à repondre de plus en plus lentement au fur et à mesur de l'utilisation

Sachant que je developpe sous linux, au lancement de tomcat, quand je liste les processus avec la commande ps aux, au départ je n'ai que 2 ou trois connexions ouvertes au niveau de la base de donné, mais au bout d'un certain temps d'utilisation, je me retrouve avec une soixantaine de connexions ouvertes sur postgres.
Je cherche à comprendre où est l'erreur que j'ai commis lors de la fermeture de la connexion au niveau des classes de la couche DAO ou au niveau du parametrage de c3p0 dans le fichier spring-config.xml

si qq pouvais m'aider, ça méviterai de devoir relancer tomcat 1 fois par heure
merci