Back

*nested-tx* (clj)

(source)

variable

Controls the behavior when a nested transaction is attempted. Possible values are: * `:allow` -- the default: assumes you know what you are doing! * `:ignore` -- the same behavior as `clojure.java.jdbc`: the nested transaction is simply ignored and any SQL operations inside it are executed in the context of the outer transaction. * `:prohibit` -- any attempt to create a nested transaction will throw an exception: this is the safest but most restrictive approach so that you can make sure you don't accidentally have any attempts to create nested transactions (since that might be a bug in your code).

Examples

camsaul/toucan2
(ns toucan2.jdbc.connection
  (:require
   [methodical.core :as m]
   [next.jdbc]
   [next.jdbc.transaction]
   [toucan2.connection :as conn]
   [toucan2.log :as log]))

(m/defmethod conn/do-with-transaction java.sql.Connection
  [^java.sql.Connection conn options f]
  (let [nested-tx-rule (get options :nested-transaction-rule next.jdbc.transaction/*nested-tx*)
        options        (dissoc options :nested-transaction-rule)]
    (log/debugf "do with JDBC transaction (nested rule: %s) with options %s" nested-tx-rule options)
    (binding [next.jdbc.transaction/*nested-tx* nested-tx-rule]
      (next.jdbc/with-transaction [t-conn conn options]
        (f t-conn)))))
dharrigan/startrek
(ns startrek.test.fixtures
  {:author "David Harrigan"}
  (:require
   [clojure.tools.logging :as log]
   [donut.system :as ds]
   [next.jdbc :as jdbc]
   [next.jdbc.transaction :as transaction]
   [startrek.test.system :as test-system]))

;; https://github.com/seancorfield/next-jdbc/blob/develop/doc/migration-from-clojure-java-jdbc.md#transactions
(def with-rollback
  (fn [f]
    (log/debug "Starting a test transaction that will be rolled back once the test has completed...")
    (let [{::ds/keys [instances]} *test-system*
          {{:keys [db]} :app-config} instances]
      (jdbc/with-transaction [tx db {:rollback-only true}]
        (binding [transaction/*nested-tx* :ignore ;;mimic the behaviour of clojure.java.jdbc, whereby the outer transaction controls the inner transaction. See link above for more info.
                  *test-system* (assoc-in *test-system* [::ds/instances :app-config :db] tx)]
          (f))))))