2016-10-13 10 views
4

テーブルm1には、何百万ものレコードがあります。テーブルm2を作成し、すべてのレコードの計算をm1にしたいと考えています。カーソルを使用しているclojure.java.jdbc内のネストされたトランザクション

(jdbc/with-db-transaction [tx connection] 
    (jdbc/query tx 
    [(jdbc/prepare-statement (:connection tx) 
           "select * from m1" 
           {:fetch-size 1000})] 
    {:result-set-fn (process! [tx result-set] ...)})) 

process!selectクエリが

(defn process! [tx result-set] 
    (jdbc/with-db-transaction [tx tx] 
    (jdbc/insert-multi! tx :m2 [:m2_column] 
     (mapv (fn [r] [(calculate r)]) 
     result-set)))) 

ですし、いい加減に消費されています 私たちは次のように、現在、それを実行しています。参照:clojure.java.jdbc lazy query。それが外部トランザクションの内部にラップされている理由です。

質問:

  • はPostgresのために問題のあるレコードが数百万の(ネストされた)トランザクションですか? clojure.java.jdbc docsでは、ネストされたトランザクションは外側のトランザクションによって吸収されるため、効果的には1つのトランザクションのみが使用されます。これは正しいです?
  • インサート用に別々のトランザクションを使用する場合は、データベースへの別の接続を使用するソリューションですか?既に接続プーリングを使用しているため、これはすでに該当する場合がありますか?

答えて

4

ネストされたトランザクションは、これは完全に真である外側の1

に吸収されています。 sources:ここにあるブランチは、すでに取引中のときに実行されます。表示されるように、funcwith-transactionマクロの本体を表す関数)は、追加設定なしで呼び出されます。

は、データベースとの別の接続を使用するソリューションですか?

clojure.java.jdbcでこれが唯一の選択肢であるようです。あなたのプールをtxの代わりにprocess!に渡すだけで機能します。問題はこれらのトランザクションがもはやネストされていないため、何らかの理由で内部トランザクションコミットと外部トランザクションが失敗した場合、内部トランザクションはロールバックされません。 raw JDBC and savepointsで「ネストされたトランザクションの動作」を達成することができます。

関連する問題