의 예를 살펴 보자 :
여기
(defn test-trans []
(let [x (ref 1)
t-inC#(dosync (alter x inc))
t-mul #(dosync (alter x (partial * 2)))
fns (flatten (repeat 10 [t-mul t-inc]))]
(last (pmap (fn [f] (f)) fns))
@x))
우리는 2 개 트랜잭션 기능을 가지고 있습니다 - 1 x
을 높이고 우리는 (20 개)와 같은 기능을 적용 (2)에 의해 x
곱 병렬 (각 가지 10)과 최종 값을 관찰 ref
입니다. 결과는 각 실행마다 다릅니다.
=> (test-trans)
2418
=> (test-trans)
2380
=> (test-trans)
1804
=> (test-trans)
4210
실제로 이것은 올바른 동작입니다. STM은 코드가 잠금없이 실행되고 변경 사항이 원자 적으로 적용됨을 보장합니다 (부분적으로 만 적용 할 수는 없음). 그러나 다른 거래 순서에 대해서도 동일한 결과를 얻을 것이라고 보장 할 수는 없습니다.
Clojure는 정확한 코드 작성을 단순화하는 훌륭한 병렬 프로그래밍 도구를 제공합니다. 그러나 이러한 종류의 경쟁 조건을 피하는 것은 개발자의 책임입니다 (사실 이러한 경우는 잘못된 시스템 설계의 명백한 징후입니다). SQL에서
또 다른 예 :이 쿼리를 병렬로 실행되는 경우
DELETE FROM tbl WHERE col=1
UPDATE tbl SET col=2 WHERE col=1
은 다음 상관없이 격리 수준 것은 거래에 사용되지 않습니다 - 결과는 순서에 따라 달라집니다.
감사합니다. 매우 유익한. –