clojure中的jdbc连接会过早地被垃圾回收

时间:2019-01-29 09:41:30

标签: jdbc clojure connection-leaks

我正在使用[com.impossibl.pgjdbc-ng/pgjdbc-ng "0.7.1"]库连接到postgres数据库。 连接保存在一个原子内。 然后,我像这样武装多个听众:

(doto (.createStatement (connection f))
    (.execute (format "LISTEN %s;" event))
    (.closeOnCompletion)))
在这种情况下,

f是事件触发时调用的函数。 由于某种原因,连接似乎被垃圾回收并不需要很长时间,这显然会使侦听器无法正常工作。

WARNING: Cleaning up leaked connection ( jdbc:pgsql://my-container/database )

此警告之后是堆栈跟踪,显示我在arm-listeners方法中打开连接的位置。

我尝试了几种方法,例如将连接存储在let中,但是似乎没有一个解决此特定问题的方法。

我使用的用于建立连接和启动侦听器的完整功能是:https://github.com/n2o/postgres-listener/blob/master/src/postgres_listener/core.clj

这是我开始听众的方式:

(defn start-listeners
  "Start all important listeners."
  []
  (connect {:host (System/getenv "DB_HOST")
            :port (read-string (System/getenv "DB_PORT"))
            :database (System/getenv "DB_NAME")
            :user (System/getenv "DB_USER")
            :password (System/getenv "DB_PW")})
  (arm-listener handle-textversions "textversions_changes")
  (arm-listener handle-statements "statements_changes")
  (arm-listener handle-arguments "arguments_changes")

1 个答案:

答案 0 :(得分:0)

看来,使用在let语句的连接和比返回它,帮助JVM不以收集参考。

所以这样的事情会有所帮助:

(let [conn (connect <...>)
      a (arm-listener f name)]
   conn)

为了让别人有另一个答案,我会暂时开放这个问题。