2013-05-01 2 views
2

Clojure에서 OrientDB 주위에 래퍼를 작성하고 있습니다. OrientDB의 가장 큰 한계 (IMHO) 중 하나는 ODatabaseDocumentTx이 스레드로부터 안전하지 않으며, .open()에서 .close()까지의 수명이 단일 트랜잭션을 나타 내기로되어있어 트랜잭션이 효과적으로 발생하도록하는 것은 단일 스레드라는 것입니다. 실제로 이러한 하이브리드 데이터베이스/트랜잭션 객체에 대한 스레드 로컬 참조는 기본적으로 제공됩니다. 하지만 "실제"상태를 유지하려는 동일한 스레드에 로그인하려면 어떻게해야합니까? 오류가 발생하면 로그 항목도 롤백됩니다! 그 사용 사례만으로는 사실상 모든 DBMS에서 벗어날 수 있습니다. 대부분의 경우 명명 된 트랜잭션 범위 관리를 허용하지 않기 때문입니다./soapboxClojure에서 단일 스레드로 수행되도록 대기 메서드 호출

어쨌든 OrientDB는 그 방법이며 나에게 변하지 않을 것입니다. Clojure를 사용하고 있는데 with-tx 본문 내의 모든 명령형 데이터베이스 호출이 직렬화되도록 with-tx 매크로를 구성하는 우아한 방법이 필요합니다.

분명히 몸체가 생성 된 with-tx의 최상위 레벨에서 전초전을 만들고 모든 양식을 최하위 수준으로 분해하여 동기화 된 블록에 배치함으로써 무차별 대입 할 수 있습니다. 그게 끔찍한데, 그게 어떻게 pmap과 상호 작용하는지 모르겠습니다.

ODatabaseDocumentTx 개체에 대한 호출을 매크로 본문에서 검색하여 동기화 된 블록으로 래핑 할 수 있습니다.

에이전트를 사용하여 일종의 디스패치 시스템을 만들 수 있습니다.

또는 ODatabaseDocumentTx를 동기화 된 메서드 호출로 하위 클래스화할 수 있습니다.

나는 다른 접근법을 생각하면서 머리를 긁적니다. 생각? 일반적으로 에이전트 접근법은 코드 블록에 데이터베이스 메소드 호출이 산재되어있는 경우 모든 계산을 앞당기 고 호출 대기열에 넣고 마지막에 DB 전체를 실행하기 때문에 에이전트 방식이 더 매력적으로 보입니다. 그러나이 계산에서는 읽기 일관성을 보장 할 필요가 없다고 가정합니다. IDK.

+0

어떤 종류의 스레드 안전하지 않은가 발생 : 하나의 "트랜잭션 개체"두 스레드에 의해 액세스 할 수 없거나 데이터베이스가 동시 기록을 지원하지 않습니다입니까? – vemv

답변

1

Lamina과 비슷한 소리입니다.

+0

Lamina를 어떻게 사용할 수 있는지 설명해 주시겠습니까? 모든 계산을 직렬화하도록 강요하고 싶지는 않습니다. 단지 I/O 비트 일 뿐이며 Lamina가 어떻게 도움이되는지 알지 못합니다. – alyssackwan

+0

Lamina를 사용하면 채널 및 파이프 라인을 사용하여 여러 가지 방법으로 부작용으로부터 계산을 분리 할 수 ​​있습니다. 상황을 동기식 또는 비동기식으로 만드는 위치와 작업이 다운 스트림을 가져 오거나 푸시하는 위치를 선택할 수 있습니다. 난 완전히 당신의 문제를보고 아니에요하지만 난 당신이 계산을 할 수 있다고 생각 멀티 스레드 및 채널 (단일 스레드) 처리를 처리기에 의해 db 호출을 다루는 이벤트를 대기열에 넣으십시오. 당신이 간단한 시나리오의 예를 든다면 아마도 더 많은 것을 도울 수있을 것입니다. – Hendekagon

0

하나의 옵션은 스레드 풀에서 1 스레드로 Executor를 사용하는 것입니다. 아래에 표시된 것과 같습니다. 이 개념을 중심으로 멋진 매크로를 만들 수 있습니다.

(import 'java.util.concurrent.Executors) 
(import 'java.util.concurrent.Callable) 

(defmacro sync [executor & body] 
    `(.get (.submit ~executor (proxy [Callable] [] 
          (call [] 
           (do [email protected])))))) 

(let [exe (Executors/newFixedThreadPool (int 1)) 
     dbtx (sync exe (DatabaseTx.))] 
    (do 
    (sync exe (readfrom dbtx)) 
    (sync exe (writeto dbtx)))) 

sync 매크로 이루는 본체 발현 실행 프로그램에서 실행되는 (하나의 스레드 만이있는)와 동작이 모든 작업을 하나씩 실행되도록 수행하는 것은 대기 중인지.

+0

요원은 거의 똑같은 일을하는 것 같습니다.에이전트 자체의 값은 트랜잭션이 될 것이고'send'는 트랜잭션과 함께 첫 번째 인수로 함수를 적용하고 체인을 허용하기 위해 트랜잭션을 리턴 할 것입니다. 이 접근 방식은 어떻게 다릅니 까? – alyssackwan

+1

에이전트는 스레드가 많은 스레드 풀을 사용하므로 DB 객체의 생성자가 표현식이 다른 스레드에서 실행될 수 있으므로 에이전트의 경우 문제가되는 것보다 스레드 로컬 항목을 생성합니다 – Ankur