【问题标题】:Streaming from MySQL with clojure.java.jdbc使用 clojure.java.jdbc 从 MySQL 流式传输
【发布时间】:2012-08-03 06:17:15
【问题描述】:

根据the release notes for the MySQL JDBC driver,当且仅当使用具有并发只读、只进结果且提取大小恰好为 Integer/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)))))))))

【问题讨论】:

标签: mysql jdbc clojure


【解决方案1】:

这个答案是指 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 指定启用流式传输的另一个要求:“连接不得处于自动提交模式。”默认情况下,连接是在启用自动提交的情况下创建的,但使用 (clojure.java.jdbc/transaction) 进行包装将在自动提交关闭的情况下运行内部代码。您也可以自己在连接上调用 .setAutoCommit。

【讨论】:

【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2015-09-22
    • 2020-11-06
    • 2012-02-06
    • 2019-12-12
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 2010-12-06
    • 1970-01-01
    相关资源
    最近更新 更多