체인코드 및 채널 전체에서 원자 갱신
원자 트랜잭션을 사용하여 원자 방식으로 채널과 체인코드 간에 여러 트랜잭션을 완료할 수 있습니다.
원자 트랜잭션은 모두 성공하거나 성공하지 못한 일련의 분할할 수 없는 데이터 작업입니다.
원자 트랜잭션은 여러 체인 코드가 별도의 채널에 배치되는 복잡한 상황에서 유용할 수 있습니다. 네트워크 또는 시스템 장애가 발생하더라도 원자 트랜잭션을 사용하여 여러 블록체인 트랜잭션을 실행하는 동안 데이터 일관성을 유지할 수 있습니다. Oracle Blockchain Platform은 2단계 커밋 프로토콜을 사용하여 원자 트랜잭션을 지원합니다. 여기서 각 데이터 작업이 준비되는 초기 단계 다음에 각 데이터 작업이 실제로 커밋되는 단계가 옵니다.
restproxy/api/v2/atomicTransactions
각 원자 거래는 둘 이상의 블록체인 거래로 구성됩니다. 원자 트랜잭션의 결과(returnCode
값)는 Success
또는 Failure
입니다. 원자 트랜잭션에서 요청된 각 블록체인 트랜잭션은 준비 단계와 커밋 단계 또는 롤백 단계라는 두 개의 개별 작업으로 분할됩니다.
- 준비 단계에서는 각 트랜잭션이 평소처럼 배서되지만, 완료되는 대신 변경 사항이 스테이지되고 다른 트랜잭션이 스테이지된 값을 수정하지 못하도록 값이 잠깁니다.
- 각 블록체인 트랜잭션에 대한 준비 단계가 성공하면 트랜잭션은 내장된 체인코드를 사용하여 승인되고 커밋됩니다. 이전에 잠긴 값은 잠금 해제되고 기본 트랜잭션 결과는
Success
입니다. - 블록체인 트랜잭션에 대한 준비 단계가 실패하면 준비 단계가 성공한 다른 모든 트랜잭션은 다시 내장된 체인코드를 사용하여 롤백됩니다. 스테이지된 변경 사항이 제거되고 이전에 잠긴 값이 잠금 해제됩니다. 원자 트랜잭션의 결과는
Failure
입니다.
- 원자 트랜잭션은 여전히 준비 단계에 있으며 다른 트랜잭션은 준비된 트랜잭션에 의해 잠긴 키를 수정하려고 시도합니다. 이 경우 시스템은 설계된 대로 작동합니다. 이 오류가 발생하면 두번째 트랜잭션을 재시도하십시오. 이는 응용 프로그램이 팬텀 읽기 오류 또는 MVCC(다중 버전 동시성 제어) 오류를 처리하는 방법과 유사합니다.
- 기본 트랜잭션에서 반환된
GlobalStatus
값은HeuristicOutcome
입니다. 이 경우 커밋 작업 중 하나가 실패하여 기본 트랜잭션 작업이 취소되었습니다. 드문 경우이지만 수동으로 해결해야 할 수도 있습니다. 휴리스틱 결과의 한 가지 부작용은 커밋되거나 롤백되지 않은 트랜잭션에 의해 일부 키가 잠긴 상태로 유지될 수 있다는 것입니다. 이 경우 다음 REST API 끝점을 사용하여 기본 트랜잭션의 잠금을 해제합니다.restproxy/api/v2/atomicTransactions/{globalTransactionId}
시나리오: 샘플을 사용하여 기본 트랜잭션 탐색
Oracle Blockchain Platform에 포함된 두 개의 샘플 체인코드인 잔액 이전 및 마블을 사용하는 다음 예를 고려해 보십시오. 잔액 이체 샘플은 계정 잔액 간에 자금을 이체할 수 있는 두 당사자를 나타냅니다. Marbles 샘플을 사용하면 대리석을 만들고 소유자 간에 교환할 수 있습니다. 잔액 이체 체인 코드에서 자금을 교환하고 Marbles 체인 코드에서 대리석 소유권을 변경하여 개별(비원자) 거래를 사용하여 대리석을 구매할 수 있습니다. 그러나 해당 거래 중 하나에서 오류가 발생하면 원장이 불일치 상태로 남을 수 있습니다. 자금이 이전되었지만 대리석이 아니거나 대리석이 이전되었지만 지급되지 않았습니다.
이 시나리오에서는 기본 트랜잭션을 지원하는 REST API 엔드포인트와 함께 기존 체인코드를 사용할 수 있습니다. 자금 교환 및 대리석 소유권 이전은 모두 성공하거나 둘 다 실패해야 합니다. 두 트랜잭션 중 하나에서 오류가 발생하면 어떤 트랜잭션도 커밋되지 않습니다. 이 시나리오를 살펴보려면 다음 단계를 완료하십시오.
- 다른 채널에 밸런스 전송 및 마블 샘플을 설치합니다. 샘플 설치에 대한 자세한 내용은 샘플을 사용하여 Oracle Blockchain Platform 살펴보기를 참조하십시오.
- Marbles 샘플에서
Create a new marble
작업을 호출하여 다양한 대리석 소유자를 위한 여러 대리석을 만듭니다. Invoke Atomic Transaction
REST 엔드포인트를 사용하여 Marbles 및 잔액 이전 샘플을 모두 호출하는 기본 트랜잭션을 완료합니다.
예를 들어, 다음 트랜잭션은 이름이 marble1
인 대리석을 Tom에게 전송하고 계정 a에서 계정 b로 50개의 동전을 전송합니다.
{
"transactions": [
{"chaincode":"obcs-marbles","args":["transferMarble", "marble1", "tom"],"timeout":0, "channel":"goods"},
{"chaincode":"obcs-example02","args":["invoke", "a", "b", "50"],"timeout":0, "channel":"wallet"}
],
"isolationLevel": "serializable",
"prepareTimeout": 10000,
"sync": true
}
이전 트랜잭션에서 두 트랜잭션이 모두 준비 단계에서 성공하면 두 트랜잭션이 모두 원장에 커밋됩니다. 두 트랜잭션 중 하나에 오류가 있으면 두번째 단계에서 트랜잭션이 커밋되지 않습니다. 대신 두 트랜잭션이 모두 롤백됩니다. 예를 들어, 계정 a에 동전이 50개 미만인 경우 계정에서 돈을 받지 않고 Tom에게 대리석이 전송되지 않습니다.
Marbles 샘플 및 Marble Owner 필드의 기본값과 관련하여 알려진 문제가 있습니다. 자세한 내용은 Oracle Blockchain Platform에 대한 알려진 문제를 참조하십시오.