Inclua o Oracle Blockchain Platform em Transações Distribuídas Globais

Seu aplicativo pode precisar fazer atualizações no razão do Oracle Blockchain Platform e em outros repositórios, como bancos de dados ou outros razões de blockchain de forma atômica, em que todas as atualizações são bem-sucedidas ou nenhuma.

Para permitir atualizações atômicas em vários bancos de dados, os desenvolvedores usam transações globais coordenadas por coordenadores de transações distribuídas, como Oracle WebLogic Server, Oracle Tuxedo, Oracle Transaction Manager for Microservices, JBoss Enterprise Application Platform, IBM WebSphere e outros sistemas. Todos esses sistemas dependem do protocolo X/Open XA para orquestrar um processo de commit de duas fases usando APIs padrão fornecidas pelos RMs (Gerenciadores de Recursos XA) para cada banco de dados ou outro recurso. O Oracle Blockchain Platform suporta commits de duas fases e fornece sua própria biblioteca XA RM, que os coordenadores de transação externos podem usar para chamar APIs compatíveis com XA. Essas transações globais também podem incluir um único recurso não XA (por exemplo, um razão de blockchain não Oracle ou um banco de dados não compatível com XA) usando uma última otimização de commit de recursos.

A especificação XA faz parte da arquitetura X/Open Distributed Transaction Processing, que define uma arquitetura padrão que permite que vários programas de aplicativos compartilhem recursos fornecidos por vários gerenciadores de recursos. A própria interface Java XA é definida como parte da plataforma Java. Para obter mais informações sobre a interface do Java XA, consulte Interface XAResource na documentação do Java.

O Oracle Blockchain Platform fornece uma biblioteca que está em conformidade com a especificação XA e implementa a interface Java padrão para um gerenciador de recursos XA. A biblioteca permite que um gerenciador de transações do lado do cliente coordene transações globais. Uma transação global é uma única unidade de trabalho que pode incluir operações como atualizações de banco de dados e transações de blockchain, todas as quais devem ser submetidas a commit atomicamente. Em outras palavras, todas as operações devem ser bem-sucedidas para serem comprometidas. Se qualquer operação que faça parte da transação global falhar, todas as operações serão submetidas a rollback. A interface XA depende do protocolo de commit de duas fases, semelhante ao protocolo suportado pelos pontos finais REST de transações atômicas. Para obter mais informações sobre transações atômicas no Oracle Blockchain Platform, consulte Fazer Atualizações Atômicas em Chaincodes e Canais.

A implementação XA para o Oracle Blockchain Platform é fornecida como uma biblioteca Java, que pode ser baixada na guia Ferramentas do Desenvolvedor no painel Desenvolvimento de Aplicativos da console do Oracle Blockchain Platform.

Detalhes completos sobre a biblioteca estão incluídos nas informações do Javadoc fornecidas no arquivo para download. Os três objetos de chave suportados pela biblioteca são OBPXAResource, OBPXADataSource e OBPXAConnection.
Objeto Objetivo
OBPXAResource Essa classe implementa as APIs necessárias para que um gerenciador de transações seja coordenado com o Oracle Blockchain Platform como um gerenciador de recursos para transações XA.
OBPXADataSource Use esse objeto para obter uma instância do OBPXAConnection e especificar as credenciais de autenticação e autorização.
OBPXAConnection Use esse objeto para obter uma instância do objeto OBPXAResource e definir as transações de blockchain a serem executadas como parte de uma transação XA.

Para usar a biblioteca XA com o Oracle Blockchain Platform, o aplicativo deve fornecer credenciais para autenticação e autorização das operações solicitadas. A biblioteca suporta tokens de acesso de autenticação básica (usuário/senha) e OAuth 2.0, que você pode configurar ao criar a instância OBPXADataSource. Os dois métodos de autenticação são consistentes com os métodos de autenticação que você usa com o proxy REST do Oracle Blockchain Platform. Para obter mais informações, consulte Autenticação na documentação da API REST.

Depois de criar uma instância OBPXADataSource, você poderá usar o método obpxaDataSource.getXAConnection() para obter a instância xaConnection. Para atualizar a autenticação ao usar tokens de acesso do OAuth 2.0, você pode usar o método getXAConnection, conforme mostrado no seguinte código:
OBPXAConnection xaConnection = obpxaDataSource.getXAConnection(accessToken);      // get an XA connection using an OAuth 2.0 access token
Você também pode usar o método getXAConnection para atualizar a autenticação básica.
OBPXAConnection xaConnection = obpxaDataSource.getXAConnection(user, password);   // get an XA connection using username and password for basic authentication
Para definir uma transação blockchain a ser executada como parte de uma transação XA global, use o seguinte método:
public void createXAInvokeTransaction​(Xid xid, OBPXAInvokeTxRequest invokeTxRequest)
Neste método, xid é um identificador de transação global e invokeTxRequest é a transação blockchain a ser executada como parte da transação XA global. Para criar uma solicitação de transação de chamada XA, use o seguinte método de construtor:
OBPXAInvokeTxRequest invokeTxRequest = new OBPXAInvokeTxRequest(channel, chaincode, args);
Neste método de construtor, channel é o canal no qual a transação de blockchain será executada, chaincode é o chaincode a ser usado e args inclui a função chaincode e quaisquer argumentos a serem usados para a transação.

O trecho de código a seguir demonstra a criação de um objeto OBPXADataSource, a obtenção da instância OBPXAConnection e, em seguida, a criação da solicitação de transação e a chamada do método createXAInvokeTransaction.

OBPXADataSource obpxaDataSource = OBPXADataSource.builder()
                        .withHost(host)
                        .withPort(port)
                        .withBasicAuth(username, password)
                        .withRole(role)
                        .build();
.
.
.
OBPXAConnection obpxaConnection = obpxaDataSource.getXAConnection();

OBPXAInvokeTxRequest invokeTxRequest = new OBPXAInvokeTxRequest(channel, chaincode, args);
invokeTxRequest.setEndorsers(endorsersArray); // optional blockchain transaction request attributes
invokeTxRequest.setTransientMap(transientMap); // optional blockchain transaction request attributes
invokeTxRequest.setTimeout(60000); // optional blockchain transaction request attributes

obpxaConnection.createXAInvokeTransaction​(xid, invokeTxRequest);

Cenário: Explorar Transações XA Usando Amostras

O cenário a seguir é semelhante ao descrito para transações atômicas: Cenário: Explorar Transações Atômicas Usando Amostras, que usa as amostras de Transferência de Saldo e Mármores incluídas no Oracle Blockchain Platform.

Nesse cenário, você instala as amostras de Transferência de Saldo e Mármores em duas instâncias diferentes do Oracle Blockchain Platform. Cada instância então corresponde a uma origem de dados XA:

  • Recurso XA OBP-1, com o chaincode Marbles instalado no canal de mercadorias
  • Recurso XA OBP-2, com o código de cadeia de Transferência de Saldo instalado no canal da wallet

Nesse cenário, você pode usar uma transação XA que abrange várias fontes de dados para garantir que a troca de fundos e a transferência de mármore ocorram de maneira atômica, em que todas as operações sejam bem-sucedidas ou nenhuma seja bem-sucedida. O código a seguir ilustra este cenário:

OBPXADataSource obpxaDS1 = ... // create an XA data source, supplying details about the OBP-1 instance
OBPXADataSource obpxaDS2 = ... // create an XA data source, supplying details about the OBP-2 instance

// start a global transaction in the client application
// invoke marble transfer on OBP-1
OBPXAConnection obpxaConn1 = (OBPXAConnection) obpxaDS1.getXAConnection();
OBPXAInvokeTxRequest invokeMarbleTransferReq = new OBPXAInvokeTxRequest("goods", "obcs-marbles", new String[]{"transferMarble", "marble1", "tom"});
obpxaConn1.createXAInvokeTransaction​(xid1, invokeMarbleTransferReq);
.
.
.
// invoke fund transfer on OBP-2
OBPXAConnection obpxaConn2 = (OBPXAConnection) obpxaDS2.getXAConnection();
OBPXAInvokeTxRequest invokeBalanceTransferReq = new OBPXAInvokeTxRequest("wallet", "obcs-example02", new String[]{"invoke", "a", "b", "50"});
obpxaConn2.createXAInvokeTransaction​(xid2, invokeBalanceTransferReq);
.
.
.
// end the global transaction in the client application

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.