JavaWebサービスからのPostgresqlデータベースの接続数に問題があります。
Spring、BoneCP、JDBCを使用しています。
複数のDAOクラスを使用してデータを取得するWebサービスがあります。このWebサービスを3回実行しても問題はありませんが、4回目は次のメッセージが表示されます。
Could not get JDBC Connection; nested exception is java.sql.SQLException: Unable to open a test connection to the given database. JDBC url = jdbc:postgresql://monserveur.com, username = pguser. Terminating connection pool. Original Exception: ------org.postgresql.util.PSQLException: FATAL: d??sol??, trop de clients sont d??j?? connect??s
これが私のWebサービスのコードです:
@GET
@Path("/launch")
@Produces(MediaType.APPLICATION_JSON)
public Response launch(@QueryParam("userId") Long userId, @QueryParam("imei") String imei) throws IOException {
Map<String, Object> m = new HashMap<String, Object>();
if (imei != null) {
UserAccount account = new UserAccount();
account.setUserId(userId);
account.setImei(imei);
if (!this.userAccountDAO.isImeiBlackListed(imei)) {
if (userId != null && userId != 0){
if(this.userAccountDAO.userExists(userId)){
if(this.userAccountDAO.userImeiExists(userId, imei)){
// Récupération des données du profil
m.put("status", account.getStatus());
m.put("forenm", account.getName());
m.put("surnm", account.getSurname());
m.put("pwd", account.getPassword());
// Récupération préférences
m.put("optin", account.hasOptedIn());
m.put("mailNotif", account.isMailNotified());
m.put("smsNotif", account.isSmsNotified());
m.put("geoloc", account.isGeolocalized());
// Récupération des adresse
m.put("addresses", this.userAddressDAO.getAddressesByUserMobile(userId));
// Récupération des moyens de paiements
m.put("mop", this.PaymentMethodDAO.getPaymentsByUserMobile(userId));
// récupération des versions
m.put("cfg", this.VersionDAO.getVersion());
m.put("nwcertif", false);
//Supression des moyens de paiement supprimés
//account.flushPaymentMethods()
m.put("nwmsg", this.NotificationDAO.hasNotification(userId));
try {
this.userAccountDAO.getJdbcTemplate().getDataSource().getConnection().close();
this.userAddressDAO.getJdbcTemplate().getDataSource().getConnection().close();
this.PaymentMethodDAO.getJdbcTemplate().getDataSource().getConnection().close();
this.VersionDAO.getJdbcTemplate().getDataSource().getConnection().close();
this.NotificationDAO.getJdbcTemplate().getDataSource().getConnection().close();
} catch (SQLException e) {
// TODO Auto-generated catch block
m.put("errcode", "09999");
}finally{
m.put("errcode", "00000");
}
//return mapper.writeValueAsString(m);
}else{
// //IMEI différent, même compte
m.put("errcode", "02005");
}
}else{
// User Id inexistant
m.put("errcode", "02006");
}
}else{
m.put("errcode", "00000");
m.put("nwmsg", false);
// récupération des versions
m.put("cfg", this.VersionDAO.getVersion());
}
}else{
// IMEI en liste noire
m.put("errcode", "02004");
}
} else {
// IMEI absent
m.put("errcode", "01020");
//return Response.serverError().entity("IMEI cannot be blank"+String.valueOf(imei)).build();
}
return Response.ok(m, MediaType.APPLICATION_JSON).build();
}
そしてここにDAOクラスの例があります:
public class JDBCUserAccountDAO implements UserAccountDAO {
private JdbcTemplate jdbcTemplate;
private SimpleJdbcInsert insertAccount;
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.insertAccount = new SimpleJdbcInsert(dataSource).withTableName(
"compte").usingGeneratedKeyColumns("idcompte");
}
/**
* @return the jdbcTemplate
*/
public JdbcTemplate getJdbcTemplate() {
return this.jdbcTemplate;
}
public boolean userExists(long userId) {
boolean result = false;
//try {
int exists = this.jdbcTemplate.queryForInt(
"SELECT COUNT(*) FROM compte WHERE idcompte=?", userId);
if (exists > 0) {
result = true;
}
/*
this.jdbcTemplate.getDataSource().getConnection().close();
} catch (SQLException e) {
// TODO Auto-generated catch block
return false;
}
*/
return result;
}
public boolean userImeiExists(Long userId, String imei) {
boolean result = false;
//try{
int exists = this.jdbcTemplate.queryForInt(
"SELECT COUNT(*) FROM compte WHERE imei=? and idcompte=?",
imei, userId);
if (exists > 0) {
result = true;
}
/*
this.jdbcTemplate.getDataSource().getConnection().close();
} catch (SQLException e) {
// TODO Auto-generated catch block
return false;
}
*/
return result;
}
と私のコグビーン:
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="idleConnectionTestPeriodInMinutes" value="240"/>
<property name="idleMaxAgeInMinutes" value="5"/>
<property name="maxConnectionsPerPartition" value="30"/>
<property name="minConnectionsPerPartition" value="10"/>
<property name="partitionCount" value="3"/>
<property name="acquireIncrement" value="5"/>
</bean>
この問題を回避するためのアイデアはありますか?
よろしくお願いします
ヴィンス