Inclure Oracle Blockchain Platform dans les transactions réparties globales

Votre application peut avoir besoin d'effectuer des mises à jour dans l'ensemble du livre Oracle Blockchain Platform et d'autres référentiels tels que les bases de données ou d'autres livres de chaîne de blocs de manière atomique, où toutes les mises à jour réussissent ou aucune ne réussissent.

Pour permettre les mises à jour atomiques sur plusieurs bases de données, les développeurs utilisent des transactions globales coordonnées par des coordinateurs de transactions distribuées tels qu'Oracle WebLogic Server, Oracle Tuxedo, Oracle Transaction Manager for Microservices, JBoss Enterprise Application Platform, IBM WebSphere et d'autres systèmes. Tous ces systèmes s'appuient sur le protocole X/Open XA pour orchestrer un processus de validation en deux phases à l'aide d'API standard fournies par les gestionnaires de ressources XA pour chaque base de données ou autre ressource. Oracle Blockchain Platform prend en charge les validations en deux phases et fournit sa propre bibliothèque RM XA, que les coordonnateurs de transactions externes peuvent utiliser pour appeler les API conformes à XA. Ces transactions globales peuvent également inclure une seule ressource non XA (par exemple, un livre de chaîne de blocs non Oracle ou une base de données non conforme à XA) à l'aide d'une optimisation de validation de la dernière ressource.

La spécification XA fait partie de l'architecture X/Open Distributed Transaction Processing, qui définit une architecture standard qui permet à plusieurs programmes d'application de partager les ressources fournies par plusieurs gestionnaires de ressources. L'interface Java XA elle-même est définie comme faisant partie de la plate-forme Java. Pour plus d'informations sur l'interface Java XA, voir Interface XAResource dans la documentation sur Java.

Oracle Blockchain Platform fournit une bibliothèque conforme à la spécification XA et met en oeuvre l'interface Java standard pour un gestionnaire de ressources XA. La bibliothèque permet à un gestionnaire de transactions côté client de coordonner les transactions globales. Une transaction globale est une unité de travail unique qui peut inclure des opérations telles que les mises à jour de base de données et les transactions de chaîne de blocs, qui doivent toutes être validées de manière atomique. En d'autres termes, toutes les opérations doivent réussir à être validées. Si une opération faisant partie de la transaction globale échoue, toutes les opérations sont annulées. L'interface XA repose sur le protocole de validation en deux phases, similaire au protocole pris en charge par les points d'extrémité REST des transactions atomiques. Pour plus d'informations sur les transactions atomiques dans Oracle Blockchain Platform, voir Faire des mises à jour atomiques sur les codes et les canaux de chaîne.

La mise en oeuvre XA pour Oracle Blockchain Platform est fournie en tant que bibliothèque Java, téléchargeable à partir de l'onglet Outils pour développeurs du volet Développement d'applications de la console Oracle Blockchain Platform.

Les détails complets sur la bibliothèque sont inclus dans les informations Javadoc fournies dans le fichier téléchargeable. Les trois objets clés pris en charge par la bibliothèque sont OBPXAResource, OBPXADataSource et OBPXAConnection.
Object Objet
OBPXAResource Cette classe met en oeuvre les API requises pour qu'un gestionnaire de transactions coordonne avec Oracle Blockchain Platform en tant que gestionnaire de ressources pour les transactions XA.
OBPXADataSource Utilisez cet objet pour obtenir une instance de OBPXAConnection et pour spécifier les données d'identification d'authentification et d'autorisation.
OBPXAConnection Utilisez cet objet pour obtenir une instance de l'objet OBPXAResource et pour définir les transactions de chaîne de blocs à exécuter dans le cadre d'une transaction XA.

Pour utiliser la bibliothèque XA avec Oracle Blockchain Platform, l'application doit fournir des données d'identification pour l'authentification et l'autorisation des opérations demandées. La bibliothèque prend en charge l'authentification de base (utilisateur/mot de passe) et les jetons d'accès OAuth 2.0, que vous pouvez configurer lors de la création de l'instance OBPXADataSource. Les deux méthodes d'authentification sont cohérentes avec les méthodes d'authentification que vous utilisez avec le mandataire REST d'Oracle Blockchain Platform. Pour plus d'informations, voir Authentification dans la documentation sur l'API REST.

Après avoir créé une instance OBPXADataSource, vous pouvez utiliser la méthode obpxaDataSource.getXAConnection() pour obtenir l'instance xaConnection. Pour mettre à jour l'authentification lors de l'utilisation de jetons d'accès OAuth 2.0, vous pouvez utiliser la méthode getXAConnection, comme indiqué dans le code suivant :
OBPXAConnection xaConnection = obpxaDataSource.getXAConnection(accessToken);      // get an XA connection using an OAuth 2.0 access token
Vous pouvez également utiliser la méthode getXAConnection pour mettre à jour l'authentification de base.
OBPXAConnection xaConnection = obpxaDataSource.getXAConnection(user, password);   // get an XA connection using username and password for basic authentication
Pour définir une transaction de chaîne de blocs à exécuter dans le cadre d'une transaction XA globale, utilisez la méthode suivante :
public void createXAInvokeTransaction​(Xid xid, OBPXAInvokeTxRequest invokeTxRequest)
Dans cette méthode, xid est un identificateur de transaction globale et invokeTxRequest est la transaction de chaîne de blocs à exécuter dans le cadre de la transaction XA globale. Pour créer une demande de transaction d'appel XA, utilisez la méthode de constructeur suivante :
OBPXAInvokeTxRequest invokeTxRequest = new OBPXAInvokeTxRequest(channel, chaincode, args);
Dans cette méthode de constructeur, channel est le canal où la transaction de chaîne de blocs sera exécutée, chaincode est le code de chaîne à utiliser et args inclut la fonction de code de chaîne et tous les arguments à utiliser pour la transaction.

L'extrait de code suivant illustre la création d'un objet OBPXADataSource, l'obtention de l'instance OBPXAConnection, puis la création de la demande de transaction et l'appel de la méthode 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);

Scénario : Explorer les transactions XA à l'aide d'échantillons

Le scénario suivant est similaire à celui décrit pour les transactions atomiques : Scénario : Explorer les transactions atomiques à l'aide d'échantillons, qui utilise les échantillons de transfert de solde et de marbre inclus avec Oracle Blockchain Platform.

Dans ce scénario, vous installez les exemples de transfert de solde et de marbre sur deux instances différentes d'Oracle Blockchain Platform. Chaque instance correspond alors à une source de données XA :

  • Ressource XA OBP-1, avec le code de chaîne Marbles installé sur le canal Biens
  • Ressource XA OBP-2, avec le code de chaîne de transfert de solde installé sur le canal de portefeuille

Dans ce scénario, vous pouvez utiliser une transaction XA qui couvre plusieurs sources de données pour vous assurer que l'échange de fonds et le transfert de marbre se produisent de manière atomique, où toutes les opérations réussissent ou aucune ne réussissent. Le code suivant illustre ce scénario :

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

Il existe un problème connu avec l'exemple Marbres et la valeur par défaut du champ Responsable du marbre. Pour plus d'informations, voir : Problèmes connus pour Oracle Blockchain Platform.