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 realizan 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 que proporcionan los gestores de recursos XA (RM) para cada base de datos u otro recurso. Oracle Blockchain Platform admite confirmaciones en dos fases y proporciona su propia biblioteca de XA RM, 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 que no sea de cadena de bloques de Oracle o una base de datos que no cumpla con XA) mediante el uso de una optimización de confirmación de último recurso.

La especificación XA es parte de la arquitectura X/Open Distributed Transaction Processing, que define una arquitectura estándar que permite a varios programas de aplicación compartir recursos proporcionados por varios gestores de recursos. La propia interfaz de Java XA se define como parte de la plataforma Java. Para obtener más información sobre la interfaz Java XA, consulte la 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 sola unidad de trabajo que podría 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 alguna 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 en los códigos y canales de cadena.

La implementación de XA para Oracle Blockchain Platform se proporciona como una biblioteca 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 admitidos 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 para 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 blockchain para que se ejecuten 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 y autenticación básica (usuario/contraseña), 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 utiliza con el proxy REST de Oracle Blockchain Platform. Puede utilizar la autenticación básica para fines de prueba 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 ejecutará como parte de la transacción XA global. 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 constructor, channel es el canal donde 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 cualquier argumento que se vaya a utilizar para la transacción.

El siguiente fragmento de código demuestra 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 muestras

El siguiente escenario es similar al descrito para las 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, instale 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:

  • El recurso XA OBP-1, con el código de cadena Marbles instalado en el canal goods
  • OBP-2 de recurso XA, 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 realicen de forma atómica, donde todas las operaciones se realicen correctamente o ninguna. 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