Includi Oracle Blockchain Platform nelle transazioni distribuite globali

La tua applicazione potrebbe dover eseguire aggiornamenti nel libro contabile Oracle Blockchain Platform e in altri repository come database o altri libri contabili blockchain in modo atomico, dove tutti gli aggiornamenti hanno successo o nessuno lo fa.

Per abilitare gli aggiornamenti atomici su più database, gli sviluppatori utilizzano transazioni globali coordinate da coordinatori delle transazioni distribuite come Oracle WebLogic Server, Oracle Tuxedo, Oracle Transaction Manager for Microservices, JBoss Enterprise Application Platform, IBM WebSphere e altri sistemi. Tutti questi sistemi si basano sul protocollo X/Open XA per orchestrare un processo di commit a due fasi utilizzando API standard fornite da XA Resource Manager (RM) per ogni database o altra risorsa. Oracle Blockchain Platform supporta i commit a due fasi e fornisce la propria libreria RM XA, che i coordinatori delle transazioni esterne possono utilizzare per richiamare le API conformi a XA. Queste transazioni globali possono anche includere una singola risorsa non XA (ad esempio, un libro contabile blockchain non Oracle o un database non conforme a XA) utilizzando un'ultima ottimizzazione del commit delle risorse.

La specifica XA fa parte dell'architettura X/Open Distributed Transaction Processing, che definisce un'architettura standard che consente a più programmi applicativi di condividere le risorse fornite da più Resource Manager. L'interfaccia XA Java è definita come parte della piattaforma Java. Per ulteriori informazioni sull'interfaccia XA Java, vedere Interfaccia XAResource nella documentazione Java.

Oracle Blockchain Platform fornisce una libreria conforme alla specifica XA e implementa l'interfaccia Java standard per un Resource Manager XA. La libreria consente a un Transaction Manager lato client di coordinare le transazioni globali. Una transazione globale è una singola unità di lavoro che potrebbe includere operazioni come aggiornamenti del database e transazioni blockchain, tutte operazioni che devono essere sottoposte a commit atomico. In altre parole, tutte le operazioni devono riuscire a essere impegnate. Se un'operazione che fa parte della transazione globale non riesce, viene eseguito il rollback di tutte le operazioni. L'interfaccia XA si basa sul protocollo di commit a due fasi, simile al protocollo supportato dagli endpoint REST delle transazioni atomiche. Per ulteriori informazioni sulle transazioni atomiche in Oracle Blockchain Platform, vedere Fai aggiornamenti atomici su codici e canali cross chain.

L'implementazione XA per Oracle Blockchain Platform viene fornita come libreria Java, scaricabile dalla scheda Strumenti per sviluppatori nel riquadro Sviluppo applicazioni della console di Oracle Blockchain Platform.

I dettagli completi sulla libreria sono inclusi nelle informazioni Javadoc fornite nel file scaricabile. I tre oggetti chiave supportati dalla libreria sono OBPXAResource, OBPXADataSource e OBPXAConnection.
Oggetto Scopo
OBPXAResource Questa classe implementa le API necessarie affinché un Transaction Manager possa coordinarsi con Oracle Blockchain Platform come Resource Manager per le transazioni XA.
OBPXADataSource Utilizzare questo oggetto per ottenere un'istanza di OBPXAConnection e specificare le credenziali di autenticazione e autorizzazione.
OBPXAConnection Utilizzare questo oggetto per ottenere un'istanza dell'oggetto OBPXAResource e definire le transazioni blockchain da eseguire come parte di una transazione XA.

Per utilizzare la libreria XA con Oracle Blockchain Platform, l'applicazione deve fornire le credenziali per l'autenticazione e l'autorizzazione delle operazioni richieste. La libreria supporta sia i token di autenticazione di base (utente/password) che i token di accesso OAuth 2.0, che è possibile configurare quando si crea l'istanza OBPXADataSource. I due metodi di autenticazione sono coerenti con i metodi di autenticazione utilizzati con il proxy REST Oracle Blockchain Platform. Per ulteriori informazioni, consulta la sezione relativa all'autenticazione nella documentazione relativa all'interfaccia API REST.

Dopo aver creato un'istanza OBPXADataSource, è possibile utilizzare il metodo obpxaDataSource.getXAConnection() per ottenere l'istanza xaConnection. Per aggiornare l'autenticazione quando si utilizzano i token di accesso OAuth 2.0, è possibile utilizzare il metodo getXAConnection, come mostrato nel codice seguente:
OBPXAConnection xaConnection = obpxaDataSource.getXAConnection(accessToken);      // get an XA connection using an OAuth 2.0 access token
È inoltre possibile utilizzare il metodo getXAConnection per aggiornare l'autenticazione di base.
OBPXAConnection xaConnection = obpxaDataSource.getXAConnection(user, password);   // get an XA connection using username and password for basic authentication
Per definire una transazione blockchain da eseguire come parte di una transazione XA globale, utilizzare il seguente metodo:
public void createXAInvokeTransaction​(Xid xid, OBPXAInvokeTxRequest invokeTxRequest)
In questo metodo, xid è un identificativo di transazione globale e invokeTxRequest è la transazione blockchain da eseguire come parte della transazione XA globale. Per creare una richiesta di transazione di richiamo XA, utilizzare il seguente metodo costruttore:
OBPXAInvokeTxRequest invokeTxRequest = new OBPXAInvokeTxRequest(channel, chaincode, args);
In questo metodo costruttore, channel è il canale in cui verrà eseguita la transazione blockchain, chaincode è il codice concatenato da utilizzare e args include la funzione codice concatenato e qualsiasi argomento da utilizzare per la transazione.

Il seguente snippet di codice mostra la creazione di un oggetto OBPXADataSource, il recupero dell'istanza OBPXAConnection, la creazione della richiesta di transazione e la chiamata del metodo 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);

Scenario: esplorazione delle transazioni XA mediante campioni

Lo scenario riportato di seguito è simile a quello descritto per le transazioni atomiche: Scenario: Explore Atomic Transactions Using Samples, che utilizza i campioni di trasferimento saldo e marmi inclusi in Oracle Blockchain Platform.

In questo scenario, è possibile installare gli esempi di trasferimento saldo e marmi su due istanze diverse di Oracle Blockchain Platform. Ogni istanza corrisponde quindi a un'origine dati XA:

  • Risorsa XA OBP-1, con il codice concatenato Marmi installato sul canale merci
  • Risorsa XA OBP-2, con il codice concatenato di trasferimento saldo installato sul canale wallet

In questo scenario, è possibile utilizzare una transazione XA che si estende su più origini dati per garantire che lo scambio di fondi e il trasferimento di marmo avvengano in modo atomico, in cui tutte le operazioni hanno successo o nessuna ha successo. Il codice seguente illustra questo scenario:

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

Si è verificato un problema noto con l'esempio Marmi e il valore predefinito del campo Proprietario marmo. Per ulteriori informazioni, vedere: Problemi noti per Oracle Blockchain Platform.