[221012] Clojure next.jdbc nested transaction with isolation rule
Table of Contents
1 nested Transaction
next.jdbc를 쓰는 경우 with-transaction
을 이용하여 중첩된 트랜잭션을 처리할 수 있다.
(defn dosth-1 [ds] (let [sql-1 ,,, sql-2 ,,,] (with-transaction [tx ds] (execute! tx sql-1) (execute! tx sql-2)))) (with-transaction [tx ds] (dosth-1 tx) (dosth-2 tx))
dosth-1
은 중첩된 트랜잭션을 만드는 장본인이다. 이렇게 된다면 트랜잭션은 각자생성되면서 dosth-2
에서 예외를 던져도
dosth-1
은 커밋이 될 것이다.
하지만 이 중첩 트랜잭션 규칙은 변경할 수 있다.
(with-transaction [tx ds] (binding [next.jdbc.transaction/*nested-tx* :ignore] (dosth-1 tx) (dosth-2 tx)))
이렇게 dynamic Var
를 변경하면 된다.
변경할 수 있는 값은 다음과 같다.
:allow
: 트랜잭션을 겹치다. (내부 트랜잭션이 덮어서 수행되고, 바깥으로 나간다):ignore
:clojure.java.jdbc
와 동일한 행동을 한다. 중첩된 내부 트랜잭션은 무시되고, 바깥 트랜잭션이 효력을 발휘함.:prohibit
: 중첩된 트랜잭션이 보이면 예외를 던진다. (이것으로 미래의 버그를 만들어 낼 수 있는 상황을 먼저 찾아낼 수 있다)
2 Isolation Rule
트랜잭션 격리룰은 첫번째 인자 벡터의 세번째 인자로 받는다.
(with-transaction [tx ds {:isolation :serializable}] (binding [next.jdbc.transaction/*nested-tx* :ignore] (dosth-1 tx) (dosth-2 tx)))
격리룰은 다음처럼 리스트업된다.
:none
, :read-committed
, :read-uncommitted
, :repeatable-read
, or :serializable
3 read-only
read-only를 위해서는 isolation rule과 동일한 방식으로 설정할 수 있다.
(with-transaction [tx ds {:isolation :serializable :read-only true}] (binding [next.jdbc.transaction/*nested-tx* :ignore] (dosth-1 tx) (dosth-2 tx)))