使用clojure.java.jdbc从MySQL流式传输

时间:2012-08-03 06:17:15

标签: mysql jdbc clojure

根据the release notes for the MySQL JDBC driver,当且仅当使用具有并发只读,仅向前结果和精确整数/ MIN_VALUE的提取大小的连接时,它才应该传输结果。

然而,当我尝试准确生成这些条件(针对[mysql/mysql-connector-java "5.1.21"])时,我的SQL查询仍然会永远运行(或者更确切地说,直到它耗尽JVM的内存并且繁荣发展)。

(let [query (query-only (fetch-all big-table))]
  (clojure.java.jdbc/with-connection (get-connection (:db query))
    (clojure.java.jdbc/with-query-results rows
      (into [{:fetch-size Integer/MIN_VALUE
              :concurrency :read-only
              :result-type :forward-only} (:sql-str query)]
            (:params query))
      (throw (Exception. (str "retrieved a row: " (pr-str (first rows)))))))))

2 个答案:

答案 0 :(得分:0)

由于with-query-results也会接受原始PreparedStatement,您可以尝试自己创建一个,显式传递所有正确的参数,看看是否有任何不同的行为。这至少会告诉您问题是clojure.java.jdbc创建PreparedStatement,还是需要深入了解驱动程序/数据库配置。

答案 1 :(得分:0)

这个答案是指postgresql而不是MySQL,但应该适用于两者。

用(clojure.java.jdbc / transaction)包装你的with-query-results函数,所以:

(let [query (query-only (fetch-all big-table))]
  (clojure.java.jdbc/with-connection (get-connection (:db query))
    (clojure.java.jdbc/transaction        
      (clojure.java.jdbc/with-query-results rows
        (into [{:fetch-size Integer/MIN_VALUE
                :concurrency :read-only
                :result-type :forward-only} (:sql-str query)]
              (:params query))
        (throw (Exception. (str "retrieved a row: " (pr-str (first rows))))))))))

The postgresql docs再次指定启用流式传输的要求:“连接不得处于自动提交模式。”默认情况下,使用autocommit on创建连接,但使用(clojure.java.jdbc / transaction)包装将运行内部代码并关闭autocommit。您也可以自己在连接上调用.setAutoCommit。