2016-10-26 1 views
1

Ich verwende Kotlin mit dem kotliquery jdbc RahmenKotliquery schließt nicht postgresql Verbindungen

einfach in ein Problem lief. Ich verwende eine Remote-PostgreSQL-Datenbank. Nach ein wenig Aufruf der Datenbank bekomme ich den folgenden Fehler Failure: too many clients already. Dies wird durch 100 Verbindungen verursacht, die idle sind.

Ich versuche, einen Punkt zu erstellen, wo ich die Konfig machen muss. Das nenne ich meinen BaseDAO. Der entsprechende Code für diese Klasse sieht wie folgt aus:

import com.zaxxer.hikari.HikariConfig 
import com.zaxxer.hikari.HikariDataSource 
import kotliquery.Session 
import kotliquery.sessionOf 
import javax.sql.DataSource 

class BaseDAO { 
    companion object { 
     var url: String = "jdbc:postgresql://server.local:5432/myDatabase" 
     var user: String = "postgres" 
     var pass: String = "postgres" 

     val config: HikariConfig = HikariConfig() 

     private fun dataSource(): DataSource 
     { 
      var hikariConfig: HikariConfig = HikariConfig(); 
      hikariConfig.setDriverClassName("org.postgresql.Driver"); 
      hikariConfig.setJdbcUrl(url); 
      hikariConfig.setUsername(user); 
      hikariConfig.setPassword(pass); 

      hikariConfig.setMaximumPoolSize(5); 
      hikariConfig.setConnectionTestQuery("SELECT 1"); 
      hikariConfig.setPoolName("springHikariCP"); 

      hikariConfig.addDataSourceProperty("dataSource.cachePrepStmts", "true"); 
      hikariConfig.addDataSourceProperty("dataSource.prepStmtCacheSize", "250"); 
      hikariConfig.addDataSourceProperty("dataSource.prepStmtCacheSqlLimit", "2048"); 
      hikariConfig.addDataSourceProperty("dataSource.useServerPrepStmts", "true"); 

      var dataSource: HikariDataSource = HikariDataSource(hikariConfig); 

      return dataSource; 
     } 

     @JvmStatic fun getSession(): Session { 
      return sessionOf(dataSource()) 
     } 
    } 

} 

Und einer meiner DAOs:

class UserDAO { 

    val toUser: (Row) -> User = { row -> 
     User(
       row.int("id"), 
       row.string("username"), 
       row.string("usertype") 
     ) 
    } 

    fun getAllUsers(): List<User> { 
     var returnedList: List<User> = arrayOf<User>().toList() 
     using(BaseDAO.getSession()) { session -> 

      val allUsersQuery = queryOf("select * from quintor_user").map(toUser).asList 
      returnedList = session.run(allUsersQuery) 
      session.connection.close() 
      session.close() 
     } 

     return returnedList 
    } 
} 

Nach einem Blick in Kotliquery Quellcode erkannte ich die session.connection.close() und session.close wäre auch nicht nötig sein, wenn Sie using (seit es eine closable schließt, die die abgerufene session ist.), Aber ohne sie habe ich den gleichen Fehler. (musste postgresql Datenbank neu starten - 100 inaktive Verbindungen).

Ich frage mich, ob es einen Fehler in meinem Code gibt oder ob das ein Fehler in Kotliquery ist?

(ebenfalls eingereicht Github Ausgabe # 6 aber dachte, die Gemeinde größer sein könnte als 24 Personen

Antwort

1

Es scheint, dass jeder Aufruf BaseDAO.getSession() neu erstellt HikariDataSource. Das bedeutet, dass jeder Session hat effektiv ist es eigene Datenbankverbindung . Pool zu beheben, dass Sie Instanz von HikariDataSource pflegen müssen anders heißt:

class BaseDAO { 
    companion object { 
     ... 
     private val dataSource by lazy { 
      var hikariConfig: HikariConfig = HikariConfig(); 
      ... 
      var dataSource: HikariDataSource = HikariDataSource(hikariConfig); 

      dataSource; 
     } 

     @JvmStatic fun getSession(): Session { 
      return sessionOf(dataSource) 
     } 
    } 

} 
+0

dank, zunächst nicht funktionierte, hatte aber eine andere Frage in Bezug auf eine andere API meine Datenbank aufrufen :) – Ivaro18