根据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)))))))))
答案 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。