문제

해야 할 거래(begin,commit,rollback),잠금(을 선택한 업데이트).나는 어떻게 그것을 문서에서 모델 db?

편집:

이 사건은 이:

  • 나를 실행하려는 경매 사이트입니다.
  • 고 생각하는 방법입니다.
  • 에서 직접 구매 나는 양을 감소하는 분야에 항목을 기록하지만,경우에만 양이다.그 이유는 내가 필요로 잠금 장치 및 트랜잭션이 있습니다.
  • 지하는 방법을 알고 있는 주소가 없이 잠금 및/또는 트랜잭션이 있습니다.

를 해결할 수 있는 이와 CouchDB?

도움이 되었습니까?

해결책

No.CouchDB 사용하는"낙관적 concurrency"모델입니다.간단한 측면에서,이 의미는 당신이 문서를 보낼 버전과 함께 당신의 업데이트 및 CouchDB 거부하는 경우 변경 현재 문서 버전이 일치하지 않은 무엇을 보냈다.

그것은 믿을 수 없 정말 간단합니다.할 수 있는 재구성한 많은 정상적인 트랜잭션 기반 시나리오에 대한 CouchDB.당신이 할 필요가 정의 밖으로 던져 당신의 RDBMS 도메인 지식을 배울 때 CouchDB,하지만.발광 다이오드 표시 스크에서 문제에 접근한 더 높은 수준,수리하는 것보다 금형 소파 SQL 입니다.

추적을 유지하의 재고

문제를 설명 주로 재고 문제입니다.이 있는 경우 문서를 설명하는 항목을 포함하고 있는 분야에 대한"사용할 수 있는 수량"를 처리할 수 있습니다 동시성 문제는 다음과 같다:

  1. 검색 문서를 주의 _rev 객실 CouchDB 보내라
  2. 감소량 필드는 경우,그것보다 더 큰 영
  3. 보 업데이트 문서 다시 사용하여, _rev
  4. 는 경우 _rev 치에 현재 저장된 번호를 수행 할 수 있습니다!
  5. 충돌이 발생하는 경우(면 _rev 일치하지 않음),검색 문서 최신 버전

이 인스턴스에서 거기는 두 가지 실패 시나리오에 대해 생각합니다.는 경우 가장 최근 문서 버전에는 수량 0,당신은 그것을 처리하는 것처럼에 RDBMS 고 사용자에게 경고하는 그들은 수 없습니다 실제로 사람들이 원하는 것입니다.는 경우 가장 최근 문서 버전에는 양보다 더 큰 0,당신은 단순히 반복하여 운영 업데이트된 데이터를,그리고 다시 시작됩니다.이제 당신은 더 많은 작업보다는 RDBMS 것,그리고 얻을 수 있는 작은 성이 있는 경우,자주 충돌하는 업데이트됩니다.

지금 대답화가 전제로 하는 당신이 일을 하는 것이 CouchDB 에서는 많은 동일한 방식으로 당신에 RDBMS.수도 방법이 이 문제는 약간 다르게:

는 주인"제품"문서 모두 포함된 설명자 데이터(이름,그림,설명,가격,etc.).그런 다음 나가는"인벤토리 티켓을"문서에 대한 각각의 특정한 인스턴스에 대한 필드 product_keyclaimed_by.만약 당신이 판매하고 있는 모델의 망치고 있는 20 개의 판매하도록 있는 문서와 같은 키 hammer-1, hammer-2, 등을 나타내는 각 사용 가능합니다.

그런 다음,나를 만들 보기에는 나의 목록을 사용 망치,으로 줄일 수있는 기능을 내게 보이는"총".이들은 완전히 팔목,그러나 당신에게 아이디어를 제공의 어떤 작업을 볼 것입니다.

지도

function(doc) 
{ 
    if (doc.type == 'inventory_ticket' && doc.claimed_by == null ) { 
        emit(doc.product_key, { 'inventory_ticket' :doc.id, '_rev' : doc._rev }); 
    } 
}

이 목록의 사용 가능한"티켓의"에 의해,제품 열쇠이다.나의 그룹을 잡고 이러한 때 누군가를 구입하려고 망치 다음,반복을 통해 업데이트를 보내(사용 id_rev 까지)내가 성공적으로 주장 중 하나(이전에는 주장 티켓될 것입 업데이트 오차).

을 줄일

function (keys, values, combine) {
    return values.length;
}

이 기능은 단순히 반 총 수의 청구 inventory_ticket 품,그래서 당신을 말할 수 있는 방법은"망치"구입할 수 있습니다.

주의 사항

이 솔루션을 나타내는 약 3.5 분의 총 생각에 대한 특정 문제에 당신이 제공됩니다.가 더 있을 수 있습니다 이 일을 하는 방법!는 말했다,그것은 실질적으로 줄일 수 충돌하는 업데이트 및 삭감하는 필요에 응답하는 갈등으로 새로운 업데이트합니다.이 모델에서,당신은 없을 것이 여러 사용자가 사용을 변경하려고 시도하는 데이터 기본 제품입니다.에서 최악의,당신은 여러 사용자가 사용하려는 주장을 하나의 티켓,당신은 여러 가지를 잡고 한 사람들의에서,당신은 단순히 다음에 이동 티켓과 다시 시도하십시오.

참고: https://wiki.apache.org/couchdb/Frequently_asked_questions#How_do_I_use_transactions_with_CouchDB.3F

다른 팁

Mrkurt의 답변에 대한 확장. 많은 시나리오의 경우 순서대로 재고 티켓을 사용할 필요가 없습니다. 첫 번째 티켓을 선택하는 대신 나머지 티켓에서 무작위로 선택할 수 있습니다. 많은 티켓과 많은 동시 요청이 주어지면, 첫 번째 티켓을 얻으려고하는 모든 사람들과 비교할 때 그 티켓에 대한 경합이 크게 줄어 듭니다.

RESTFULL 트랜잭션의 설계 패턴은 시스템에서 "장력"을 만드는 것입니다. 은행 계좌 거래의 인기있는 예제 사용 사례의 경우 관련 계정에 대한 총계를 업데이트해야합니다.

  • 거래 문서 "계정 11223에서 계정 88733으로 송금 10"을 작성하십시오. 이것은 시스템에서 장력을 만듭니다.
  • 모든 트랜잭션 문서에 대한 장력 스캔을 해결하려면
    • 소스 계정이 업데이트되지 않은 경우 소스 계정 (-10 USD)을 업데이트합니다.
    • 소스 계정이 업데이트되었지만 트랜잭션 문서 에이 표시가 표시되지 않으면 트랜잭션 문서를 업데이트합니다 (예 : 문서에서 "SourcedOne"을 설정하십시오)
    • 대상 계정이 업데이트되지 않은 경우 대상 계정 (+10 USD)을 업데이트합니다.
    • 대상 계정이 업데이트되었지만 트랜잭션 문서에 표시되지 않으면 트랜잭션 문서를 업데이트합니다.
    • 두 계정 모두 업데이트 된 경우 거래 문서를 삭제하거나 감사를 위해 보관할 수 있습니다.

장력 스캔은 시스템의 장력 시간을 짧게 유지하기 위해 모든 "장력 문서"에 대한 백엔드 프로세스에서 수행해야합니다. 위의 예에서는 첫 번째 계정이 업데이트되었을 때 단기간의 예상 불일치가 있지만 두 번째 계정은 아직 업데이트되지 않았습니다. CouchDB가 배포 된 경우 최종 일관성을 다루는 것과 동일한 방식으로 고려해야합니다.

또 다른 구현은 트랜잭션의 필요성을 완전히 피하십시오. 장력 문서를 저장하고 관련된 모든 긴장 문서를 평가하여 시스템 상태를 평가하십시오. 위의 예에서는 계정의 총계 가이 계정이 관련된 거래 문서의 합계 값으로 만 결정된다는 것을 의미합니다. CouchDB에서는 맵/축소보기로 이것을 아주 멋지게 모델링 할 수 있습니다.

아니요, CouchDB는 클러스터/복제 환경에서 원자 운영을 지원하지 않기 때문에 일반적으로 트랜잭션 응용 프로그램에 적합하지 않습니다.

CouchDB는 확장 성을 위해 거래 능력을 희생했습니다. 원자 연산을하려면 중앙 조정 시스템이 필요하므로 확장 성을 제한합니다.

COUCHDB 인스턴스가 하나만 있거나 특정 문서를 수정하는 모든 사람이 동일한 CouchDB 인스턴스에 연결되도록 보장 할 수 있다면 충돌 감지 시스템을 사용하여 위에서 설명한 방법을 사용하여 일종의 원자력을 만들 수 있지만 나중에 클러스터까지 확장하는 경우. 또는 Cloudant와 같은 호스팅 된 서비스를 사용하여 분해되며 시스템의 해당 부분을 다시 만들어야합니다.

따라서 내 제안은 귀하의 계정 잔액에 CouchDB 이외의 것을 사용하는 것입니다. 그런 식으로 훨씬 쉬울 것입니다.

OP의 문제에 대한 응답으로 소파는 아마도 최선의 선택이 아닐 것입니다. 보기를 사용하는 것은 재고를 추적하는 좋은 방법이지만 0으로 클램핑하는 것은 거의 불가능합니다. 문제는 뷰의 결과를 읽을 때 인종 조건이므로 "해머 -1"항목을 사용해도 괜찮다고 결정한 다음 문서를 작성하여 사용하십시오. 문제는보기의 결과가> 0 Hammer-1이 있다는 것인 경우 해머를 사용하기 위해 문서를 작성하는 원자력 방법이 없다는 것입니다. 100 명의 사용자가 모두 동시에보기를 쿼리하고 1 Hammer-1을 보면 Doc을 작성하여 Hammer 1을 사용하여 -99 Hammer-1을 초래할 수 있습니다. 실제로, DB가 LocalHost를 실행하는 경우 레이스 조건은 상당히 작습니다. 그러나 일단 확장하고 오프 사이트 DB 서버 또는 클러스터가 있으면 문제가 훨씬 눈에 띄게됩니다. 그럼에도 불구하고, 중요한 돈 관련 시스템에서 그러한 종류의 인종 조건을 갖는 것은 용납 할 수 없습니다.

Mrkurt의 답변에 대한 업데이트 (단지 날짜가되었거나 일부 CouchDB 기능을 알지 못했을 수도 있습니다)

보기는 CouchDB의 잔액 / 인벤토리와 같은 것을 처리하는 좋은 방법입니다.

당신은 문서를 방출 할 필요가 없습니다. 보기 결과를 검색 할 때 두 가지를 모두 무료로 얻습니다. 그들을 방출하는 것, 특히 사전과 같은 장점 형식으로, 불필요하게 당신의 견해가 커질 것입니다.

인벤토리 잔액 추적을위한 간단한 모습은 이것처럼 보일 것입니다 (또한 내 머리 꼭대기에서도)

function( doc )
{
    if( doc.InventoryChange != undefined ) {
        for( product_key in doc.InventoryChange ) {
            emit( product_key, 1 );
        }
    }
}

그리고 감소 기능은 훨씬 더 간단합니다

_sum

이것은 a를 사용합니다 내장 기능 감소 기능 그것은 단지 모든 행의 값을 일치하는 키로 요약합니다.

이 관점에서, 모든 문서는 Product_key를 맵핑하는 멤버 "InventoryChange"를 가질 수 있습니다. 즉.

{
    "_id": "abc123",
    "InventoryChange": {
         "hammer_1234": 10,
         "saw_4321": 25
     }
}

10 개의 Hammer_1234와 25 SAW_4321을 추가합니다.

{
    "_id": "def456",
    "InventoryChange": {
        "hammer_1234": -5
    }
}

인벤토리에서 5 개의 해머를 태울 것입니다.

이 모델을 사용하면 데이터를 업데이트하지 않으며 추가됩니다. 이것은 업데이트 충돌 기회가 없다는 것을 의미합니다. 데이터 업데이트의 모든 트랜잭션 문제는 사라집니다 :)

이 모델의 또 다른 좋은 점은 DB의 모든 문서가 인벤토리에서 항목을 추가하고 빼낼 수 있다는 것입니다. 이 문서에는 모든 종류의 다른 데이터가있을 수 있습니다. 수신 된 날짜 및 시간, 창고, 직원 등에 대한 많은 데이터가 포함 된 "배송"문서가있을 수 있으며 DOC가 재고 교환을 정의하는 한 재고를 업데이트합니다. "판매"문서와 "손상된"문서 등을 할 수 있듯이 각 문서를 살펴보면 매우 명확하게 읽습니다. 그리고 견해는 모든 노력을 처리합니다.

실제로, 당신은 어떤 식 으로든 할 수 있습니다. 살펴보십시오 HTTP 문서 API 제목 "단일 요청으로 여러 문서를 수정"으로 스크롤하십시오.

기본적으로 단일 게시물 요청으로 여러 문서를 작성/업데이트/삭제할 수 있습니다. uri /{dbname} /_ bulk_docs 그리고 그들은 모두 성공하거나 모두 실패 할 것입니다. 그러나이 문서는이 동작이 미래에 변할 수 있다고 경고합니다.

편집 : 예측 된 바와 같이, 버전 0.9에서 벌크 문서는 더 이상 이런 식으로 작동하지 않습니다.

트랜잭션에 SQLITE 종류의 경량 솔루션을 사용하고 트랜잭션이 완료되면 성공적으로 복제하고 SQLITE에서 복제되었습니다.

sqlite 테이블

txn_id    , txn_attribute1, txn_attribute2,......,txn_status
dhwdhwu$sg1   x                    y               added/replicated

복제 된 트랜잭션을 성공적으로 삭제할 수도 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top