4

MySQL JDBCドライバーのリリースノートによると、同時実行の読み取り専用、転送専用の結果、および正確に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)))))))))
4

2 に答える 2

0

with-query-resultsは生のP​​reparedStatementも受け入れるので、自分で作成して、すべての正しいパラメーターを明示的に渡して、別の動作が得られるかどうかを確認してみてください。これにより、少なくとも、clojure.java.jdbcがPreparedStatementを作成することに問題があるのか​​、それともドライバー/データベース構成を詳しく調べる必要があるのか​​がわかります。

于 2012-08-03T13:55:08.053 に答える
0

この回答はMySQLではなくpostgresqlを参照していますが、両方に当てはまるはずです。

with-query-results関数を(clojure.java.jdbc / transaction)でラップすると、次のようになります。

(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))))))))))

postgresqlのドキュメントでは、ストリーミングを有効にするためのもう1つの要件を指定しています。「接続は自動コミットモードであってはなりません。」デフォルトでは、接続は自動コミットをオンにして作成されますが、(clojure.java.jdbc / transaction)でラップすると、自動コミットをオフにして内部コードが実行されます。接続で.setAutoCommitを自分で呼び出すこともできます。

于 2012-08-29T00:22:01.427 に答える