2015-02-01 2 views
3

안녕하세요 저는 clojure에 대한 책의 즐거움을 읽었으며 STM에 관한 섹션에서 그들은 A가 처음에 B가있는 ref에서 동일한 값을 검색하고 두 트랜잭션 A와 B가 계산을 수행하지만 A가 먼저 완료되고 변수에 커밋을 수행하므로 B가 다시 시도해야합니다.Clojure stm의 인종 조건?

하지만 B가 A의 커밋으로 다시 시도했는지에 대해 숙고하고 있습니다. 그게 사실이라면 그 반대의 경우는 어떨까요? 그렇다면 최종 가치는 분명히 다를 것입니다.

이것은 간단히 간과 한 것으로 보이며, 나는 그것을 완전히 이해하지 못한다고 생각합니다. 이 문제를 해결할 수 있도록 도와주세요.

답변

6

의 예를 살펴 보자 :

여기
(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 

은 다음 상관없이 격리 수준 것은 거래에 사용되지 않습니다 - 결과는 순서에 따라 달라집니다.

+0

감사합니다. 매우 유익한. –