Fixes #117 by providing control over nested transactions
This commit is contained in:
parent
fbbd2b5d4d
commit
e9c1bda637
2 changed files with 36 additions and 7 deletions
|
|
@ -2,11 +2,10 @@
|
|||
|
||||
Only accretive/fixative changes will be made from now on.
|
||||
|
||||
* WIP: nested transaction support!
|
||||
|
||||
Changes made since the 1.0.478 release:
|
||||
* Address #125 by making the result of `plan` foldable (in the `clojure.core.reducers` sense).
|
||||
* Address #124 by extending `next.jdbc.sql.builder/for-query` to support `:top` (SQL Server), `:limit` / `:offset` (MySQL/PostgreSQL), `:offset` / `:fetch` (SQL Standard).
|
||||
* Address #117 by adding `next.jdbc.transaction/*nested-tx*` to provide control over how attempts to create nested transactions should be handled.
|
||||
* Address #116 by adding a `:multi-rs` option to `execute!` to retrieve multiple result sets, for example from stored procedure calls or T-SQL scripts.
|
||||
* Allow `:all` to be passed into `find-by-keys` instead of an example hash map or a where clause vector so all rows will be returned (expected to be used with `:offset` etc to support simple pagination of an entire table).
|
||||
* Add `:columns` option to `find-by-keys` (and `get-by-id`) to specify a subset of columns to be returned in each row. This can also specify an alias for the column and allows for computed expressions to be selected with an alias.
|
||||
|
|
|
|||
|
|
@ -1,12 +1,45 @@
|
|||
;; copyright (c) 2018-2020 Sean Corfield, all rights reserved
|
||||
|
||||
(ns ^:no-doc next.jdbc.transaction
|
||||
"Implementation of SQL transaction logic."
|
||||
(ns next.jdbc.transaction
|
||||
"Implementation of SQL transaction logic.
|
||||
|
||||
In general, you cannot nest transactions. `clojure.java.jdbc` would
|
||||
ignore any attempt to create a nested transaction, even tho' some
|
||||
databases do support it. `next.jdbc` allows you to call `with-transaction`
|
||||
even while you are inside an active transaction, but the behavior may
|
||||
vary across databases and the commit or rollback boundaries may not be
|
||||
what you expect. In order to avoid two transactions constructed on the
|
||||
same connection from interfering with each other, `next.jdbc` locks on
|
||||
the `Connection` object (this prevents concurrent transactions on separate
|
||||
threads from interfering but will cause deadlock on a single thread --
|
||||
so beware).
|
||||
|
||||
Consequently, this namespace exposes a dynamic variable, `*nested-tx*`,
|
||||
which can be used to vary the behavior when an attempt is made to start
|
||||
a transaction when you are already inside a transaction."
|
||||
(:require [next.jdbc.protocols :as p])
|
||||
(:import (java.sql Connection)))
|
||||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
||||
(defonce ^:dynamic
|
||||
^{:doc "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)."}
|
||||
*nested-tx*
|
||||
:allow)
|
||||
|
||||
(defonce ^:private ^:dynamic ^{:doc "Used to detect nested transactions."}
|
||||
*active-tx* false)
|
||||
|
||||
(def ^:private isolation-levels
|
||||
"Transaction isolation levels."
|
||||
{:none Connection/TRANSACTION_NONE
|
||||
|
|
@ -79,9 +112,6 @@
|
|||
(.setReadOnly con old-readonly)
|
||||
(catch Exception _))))))))
|
||||
|
||||
(defonce ^:dynamic ^{:doc ""} *nested-tx* :allow)
|
||||
(defonce ^:private ^:dynamic ^{:doc ""} *active-tx* false)
|
||||
|
||||
(extend-protocol p/Transactable
|
||||
java.sql.Connection
|
||||
(-transact [this body-fn opts]
|
||||
|
|
|
|||
Loading…
Reference in a new issue