Incluir Oracle Blockchain Platform en transacciones distribuidas globales

Es posible que su aplicación necesite realizar actualizaciones en el libro mayor de Oracle Blockchain Platform y en otros repositorios, como bases de datos u otros libros mayores de blockchain, de forma atómica, donde todas las actualizaciones se realicen correctamente o ninguna.

Para activar las actualizaciones atómicas en varias bases de datos, los desarrolladores utilizan transacciones globales coordinadas por coordinadores de transacciones distribuidas como Oracle WebLogic Server, Oracle Tuxedo, Oracle Transaction Manager for Microservices, JBoss Enterprise Application Platform, IBM WebSphere y otros sistemas. Todos estos sistemas se basan en el protocolo X/Open XA para orquestar un proceso de confirmación en dos fases mediante el uso de API estándar proporcionadas por los gestores de recursos (RM) de XA para cada base de datos u otro recurso. Oracle Blockchain Platform soporta confirmaciones en dos fases y proporciona su propia biblioteca XA RM, que los coordinadores de transacciones externos pueden utilizar para llamar a API compatibles con XA. Estas transacciones globales también pueden incluir un único recurso que no sea XA (por ejemplo, un libro mayor de blockchain que no sea de Oracle o una base de datos que no sea compatible con XA) mediante una optimización de confirmación de último recurso.

La especificación XA forma parte de la arquitectura X/Open Distributed Transaction Processing, que define una arquitectura estándar que permite que varios programas de aplicación compartan recursos proporcionados por varios gestores de recursos. La propia interfaz Java XA se define como parte de la plataforma Java. Para obtener más información sobre la interfaz Java XA, consulte Interfaz XAResource en la documentación de Java.

Oracle Blockchain Platform proporciona una biblioteca que cumple con la especificación XA e implementa la interfaz Java estándar para un gestor de recursos XA. La biblioteca permite que un gestor de transacciones del cliente coordine transacciones globales. Una transacción global es una sola unidad de trabajo que puede incluir operaciones como actualizaciones de bases de datos y transacciones de blockchain, todas las cuales deben confirmarse atómicamente. En otras palabras, todas las operaciones se deben confirmar correctamente. Si falla cualquier operación que forme parte de la transacción global, se realiza un rollback de todas las operaciones. La interfaz XA se basa en el protocolo de confirmación en dos fases, similar al protocolo soportado por los puntos finales de REST de transacciones atómicas. Para obtener más información sobre las transacciones atómicas en Oracle Blockchain Platform, consulte Realización de actualizaciones atómicas entre códigos de cadena y canales.

La implantación de XA para Oracle Blockchain Platform se proporciona como una biblioteca Java, que se puede descargar desde el separador Herramientas de desarrollador del panel Desarrollo de aplicaciones de la consola de Oracle Blockchain Platform.

Los detalles completos sobre la biblioteca se incluyen en la información de Javadoc proporcionada en el archivo descargable. Los tres objetos clave admitidos por la biblioteca son OBPXAResource, OBPXADataSource y OBPXAConnection.
Objecto Finalidad
OBPXAResource Esta clase implanta las API necesarias para que un gestor de transacciones se coordine con Oracle Blockchain Platform como gestor de recursos para transacciones XA.
OBPXADataSource Utilice este objeto para obtener una instancia de OBPXAConnection y para especificar las credenciales de autenticación y autorización.
OBPXAConnection Utilice este objeto para obtener una instancia del objeto OBPXAResource y para definir las transacciones de blockchain que se van a ejecutar como parte de una transacción XA.

Para utilizar la biblioteca XA con Oracle Blockchain Platform, la aplicación debe proporcionar credenciales para la autenticación y autorización de las operaciones solicitadas. La biblioteca admite tokens de acceso de autenticación básica (usuario/contraseña) y OAuth 2.0, que puede configurar al crear la instancia OBPXADataSource. Los dos métodos de autenticación son coherentes con los métodos de autenticación que se utilizan con el proxy REST de Oracle Blockchain Platform. Puede utilizar la autenticación básica para pruebas y desarrollo interno. No utilice la autenticación básica en entornos de producción. Para obtener más información, consulte Autenticación en la documentación de la API de REST.

Después de crear una instancia OBPXADataSource, puede utilizar el método obpxaDataSource.getXAConnection() para obtener la instancia xaConnection. Para actualizar la autenticación al utilizar tokens de acceso OAuth 2.0, puede utilizar el método getXAConnection, como se muestra en el siguiente código:
OBPXAConnection xaConnection = obpxaDataSource.getXAConnection(accessToken);      // get an XA connection using an OAuth 2.0 access token
También puede utilizar el método getXAConnection para actualizar la autenticación básica.
OBPXAConnection xaConnection = obpxaDataSource.getXAConnection(user, password);   // get an XA connection using username and password for basic authentication
Para definir una transacción de blockchain que se ejecutará como parte de una transacción XA global, utilice el siguiente método:
public void createXAInvokeTransaction​(Xid xid, OBPXAInvokeTxRequest invokeTxRequest)
En este método, xid es un identificador de transacción global y invokeTxRequest es la transacción de cadena de bloques que se va a ejecutar como parte de la transacción XA global. Para crear una solicitud de transacción de llamada de XA, utilice el siguiente método constructor:
OBPXAInvokeTxRequest invokeTxRequest = new OBPXAInvokeTxRequest(channel, chaincode, args);
En este método de constructor, channel es el canal donde se ejecutará la transacción de cadena de bloques, chaincode es el código de cadena que se utilizará y args incluye la función de código de cadena y cualquier argumento que se utilice para la transacción.

El siguiente fragmento de código muestra la creación de un objeto OBPXADataSource, la obtención de la instancia OBPXAConnection y, a continuación, la creación de la solicitud de transacción y la llamada al 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);

Escenario: Exploración de transacciones de XA mediante muestras

El siguiente escenario es similar al descrito para transacciones atómicas: Escenario: Exploración de transacciones atómicas mediante muestras, que utiliza los ejemplos de transferencia de saldo y mármoles que se incluyen con Oracle Blockchain Platform.

En este escenario, instalará los ejemplos de transferencia de saldo y mármoles en dos instancias diferentes de Oracle Blockchain Platform. A continuación, cada instancia se corresponde con un origen de datos XA:

  • Recurso XA OBP-1, con el código de cadenas Marbles instalado en el canal goods.
  • Recurso XA OBP-2, con el código de cadena de transferencia de saldo instalado en el canal de cartera

En este escenario, puede utilizar una transacción XA que abarque varios orígenes de datos para garantizar que el intercambio de fondos y la transferencia de mármol se produzcan de manera atómica, donde todas las operaciones se realicen correctamente o ninguna correcta. El siguiente código ilustra este escenario:

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