2016-07-11 10 views
1

Berkeley DB에서 비교 및 ​​스왑 연산을 효율적으로 구현하는 방법을 찾고 있습니다. 지금은 정말 오래된 버전을 사용하고 있지만, 언뜻보기에는 최신 버전 (Oracle 웹 사이트에서 배포)에도 이러한 작업을위한 단일 방법이 없습니다. 나는 다음과 같은 의미를 가진버클리 DB JE에서 비교 및 ​​교체 하시겠습니까?

replace(Transaction, Key, ExpectedValue, NewValue) 

같은 방법의 어떤 종류를 찾고 있었다

:이 값이 존재하고 그 다음이 값이 될 것입니다 expectedValue를 동일한 경우 DB는 주어진 키와 관련된 값을 가져옵니다 NewValue로 변경되고, 그렇지 않으면 메소드가 실패한 OperationStatus를 반환합니다.

이렇게 보이는 방법이없는 것처럼 보이므로이 방법이 가장 효율적인 방법으로 수행되어야한다고 생각합니다.

는 지금은 다음과 같은 방법을 사용하고 있습니다 : 그들은 내가 이전 버전을 삭제 최종 갱신을 일치하는 경우 나,

db.get(null, key) -> {currentValue, version} 
db.put(null, key, {currentValue, newRandomIdVersion}) 
db.get(null, key) 

내가 가치와 버전을 비교 않습니다. 단계가 실패하면 전체 프로세스가 재시작됩니다.

나는 이것이 매우 차선책이라고 생각한다. 나는 틀린가?

+0

아무 것도 시도해 보지 않으셨습니까? –

+0

첫 번째 균열로 트랜잭션을 사용하여 성능이 충분한 지 확인하십시오. –

+0

트랜잭션 내에서 카운터를 업데이트하는 것입니까? 그것은 도움이되지 않을 것입니다 - 동시 트랜잭션은 스스로를 오버라이드 할 것입니다. – Alex

답변

0

내 질문에 대한 내 업데이트 솔루션이 잘못되었습니다. 그러나 더 나은 수정을 위해서는 약간의 수정 만 필요합니다.

솔루션은 다음과 같을 수 있습니다. 일부 카운터와 키 연관을 유지할 잠금 저장 용 별도의 DB를 만듭니다. 이 DB는 정렬 된 중복을 허용해야합니다 (Database.get은 주어진 키와 연관된 가장 작은 값을 반환합니다). 그런 다음 공유 단조 증가 카운터를 사용하십시오. CAS를 시도하는 여러 스레드는이 카운터에서 값을 가져 와서 해당 키 DB에 키 - 값 쌍을 저장합니다. 쓰레드가 키와 관련된 가장 낮은 값을 저장하고, 쓰기 권한이 있다고 가정하고 원하는 레코드에 대한 비교 - 스왑을 수행 한 다음 잠금 DB에서 엔트리를 삭제하고 다른 쓰레드는 재 시도합니다.