Faça Atualizações Atômicas em Chaincodes e Canais
Você pode usar transações atômicas para concluir várias transações entre canais e códigos de cadeia de maneira atômica.
Uma transação atômica é uma série indivisível de operações de dados que são bem-sucedidas ou nenhuma é bem-sucedida.
As transações atômicas podem ser úteis em situações complexas em que vários códigos de cadeia são implantados em canais separados. Você pode usar transações atômicas para manter a consistência dos dados ao executar várias transações blockchain, mesmo que ocorra uma falha na rede ou no sistema. O Oracle Blockchain Platform suporta transações atômicas usando o protocolo de commit de duas fases, em que uma fase inicial em que cada operação de dados é preparada é seguida por uma fase em que cada operação de dados é realmente confirmada.
restproxy/api/v2/atomicTransactions
Cada transação atômica é composta por duas ou mais transações blockchain. O resultado (o valor returnCode
) da transação atômica é Success
ou Failure
. Em uma transação atômica, cada transação de blockchain solicitada é dividida em duas operações distintas: uma fase de preparação e, em seguida, uma fase de commit ou de rollback.
- Na fase de preparação, cada transação é endossada normalmente, mas em vez de ser finalizada, as alterações são preparadas e os valores são bloqueados para evitar que outras transações modifiquem os valores preparados.
- Se a fase de preparação for bem-sucedida para cada transação de blockchain, as transações serão endossadas e confirmadas usando o chaincode integrado. Os valores bloqueados anteriormente são desbloqueados e o resultado da transação atômica é
Success
. - Se a fase de preparação falhar para qualquer transação blockchain, todas as outras transações em que a fase de preparação foi bem-sucedida serão revertidas, novamente usando o chaincode incorporado. As alterações preparadas são removidas e os valores bloqueados anteriormente são desbloqueados. O resultado da transação atômica é
Failure
.
- Uma transação atômica ainda está na fase preparada, e outra transação tenta modificar uma chave que foi bloqueada pela transação preparada. Nesse caso, o sistema está funcionando conforme projetado. Se você encontrar esse erro, repita a segunda transação. Isso é análogo a como os aplicativos lidam com erros de leitura fantasma ou erros de controle de simultaneidade de várias versões (MVCC).
- O valor
GlobalStatus
retornado pela transação atômica éHeuristicOutcome
. Nesse caso, uma operação de transação atômica foi cancelada porque uma das operações de commit falhou. Esta é uma ocorrência rara e pode precisar ser resolvida manualmente. Um efeito colateral de um resultado heurístico é que algumas chaves podem ser deixadas bloqueadas por transações que não foram submetidas a commit ou a rollback. Nesse caso, use o seguinte ponto final da API REST para desbloquear a transação atômica:restproxy/api/v2/atomicTransactions/{globalTransactionId}
Cenário: Explorar Transações Atômicas Usando Amostras
Considere o exemplo a seguir, que usa dois dos exemplos de códigos de cadeia incluídos no Oracle Blockchain Platform, Balance Transfer e Marbles. A amostra de Transferência de Saldo representa duas partes com a capacidade de transferir fundos entre saldos de conta. A amostra de mármores permite que você crie mármores e troque-os entre os proprietários. Você pode usar transações individuais (não atômicas) para comprar um mármore trocando fundos no código de cadeia de Transferência de Saldo e alterando a propriedade do mármore no código de cadeia de Mármores. No entanto, se ocorrer um erro com uma dessas transações, o razão poderá ficar em um estado inconsistente: ou os fundos foram transferidos, mas não o mármore ou o mármore é transferido, mas não pago.
Nesse cenário, você pode usar o chaincode existente com os pontos finais da API REST que suportam transações atômicas. A troca de fundos e a transferência de propriedade do mármore devem ter sucesso ou ambos falharem. Se uma das transações encontrar um erro, nenhuma delas será confirmada. Para explorar esse cenário, execute as seguintes etapas:
- Instale as amostras de Transferência de Saldo e Mármores em diferentes canais. Para obter mais informações sobre como instalar as amostras, consulte Explorar o Oracle Blockchain Platform Usando Amostras.
- Na amostra Mármores, chame a ação
Create a new marble
para criar vários mármores para vários proprietários de mármore. - Use o ponto final REST
Invoke Atomic Transaction
para concluir transações atômicas que chamam as amostras de Mármores e Transferência de Saldo.
Por exemplo, a transação a seguir transfere um mármore chamado marble1
para Tom e envia 50 moedas da conta a para a conta b.
{
"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
}
Na transação anterior, se ambas as transações forem bem-sucedidas na fase de preparação, ambas as transações serão confirmadas no razão. Se houver um erro com uma das transações, nenhuma delas será confirmada durante a segunda fase. Em vez disso, ambas as transações são submetidas a rollback. Por exemplo, se houver menos de 50 moedas na conta a, nenhum dinheiro será retirado da conta e nenhum mármore será transferido para Tom.
Há um problema conhecido com a amostra Mármores e o valor padrão do campo Proprietário do mármore. Para obter mais informações, consulte: Problemas Conhecidos do Oracle Blockchain Platform.