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