Incluir Oracle Blockchain Platform en transacciones distribuidas globales

Puede que la 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 confían en el protocolo X/Open XA para orquestar un proceso de confirmación en dos fases mediante el uso de API estándar que proporcionan los gestores de recursos XA (RM) para cada base de datos u otro recurso. Oracle Blockchain Platform soporta confirmaciones en dos fases y proporciona su propia biblioteca RM de XA, que los coordinadores de transacciones externas pueden utilizar para llamar a API compatibles con XA. Estas transacciones globales también pueden incluir un único recurso no XA (por ejemplo, un libro mayor de blockchain no de Oracle o una base de datos no compatible con XA) mediante una última optimización de confirmación de recursos.

La especificación XA forma parte de la arquitectura de procesamiento de transacciones distribuidas X/Open, que define una arquitectura estándar que permite que varios programas de aplicación compartan los 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 de 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 a un gestor de transacciones del cliente coordinar transacciones globales. Una transacción global es una única unidad de trabajo que puede incluir operaciones como actualizaciones de bases de datos y transacciones de blockchain, todas las cuales deben confirmarse de forma atómica. En otras palabras, todas las operaciones se deben confirmar correctamente. Si falla alguna operación que forma 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 en los códigos de cadenas y canales.

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

Los detalles completos de la biblioteca se incluyen en la información de Javadoc proporcionada en el archivo descargable. Los tres objetos clave soportados por la biblioteca son OBPXAResource, OBPXADataSource y OBPXAConnection.
Objecto Finalidad
OBPXAResource Esta clase implementa 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 especificar las credenciales de autenticación y autorización.
OBPXAConnection Utilice este objeto para obtener una instancia del objeto OBPXAResource y definir las transacciones de cadena de bloques que se ejecutarán 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 OAuth 2.0 (usuario/contraseña) y autenticación básica, que puede configurar al crear la instancia OBPXADataSource. Los dos métodos de autenticación son consistentes con los métodos de autenticación que se utilizan con el proxy REST de Oracle Blockchain Platform. 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 cadena de bloques 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 global de XA. Para crear una solicitud de transacción de llamada XA, utilice el siguiente método de constructor:
OBPXAInvokeTxRequest invokeTxRequest = new OBPXAInvokeTxRequest(channel, chaincode, args);
En este método de constructor, channel es el canal en el que se ejecutará la transacción de cadena de bloques, chaincode es el código de cadena que se va a utilizar y args incluye la función de código de cadena y los argumentos que se van a utilizar 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 XA mediante ejemplos

El siguiente escenario es similar al descrito para las transacciones atómicas: Escenario: Explorar transacciones atómicas mediante muestras, que utiliza los ejemplos de transferencia de balance 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 cadena Marbles instalado en el canal de bienes
  • Recurso XA OBP-2, con el código de cadena de transferencia de balance 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 realizan de forma atómica, donde todas las operaciones se realizan correctamente o ninguna se realiza correctamente. 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

Se ha producido un problema conocido con el ejemplo de mármoles y el valor por defecto del campo Propietario de mármol. Para obtener más información, consulte: Cuestiones conocidas de Oracle Blockchain Platform.