グローバル分散トランザクションにOracle Blockchain Platformを含める

アプリケーションでは、Oracle Blockchain Platform台帳およびその他のリポジトリ(データベースやその他のブロックチェーン台帳など)を原子的な方法で更新する必要がある場合があります。すべての更新が成功するか、まったく成功しないかのいずれかです。

複数のデータベース間でアトミック更新を有効にするには、開発者は、Oracle WebLogic Server、Oracle Tuxedo、Oracle Transaction Manager for Microservices、JBoss Enterprise Application Platform、IBM WebSphereなどの分散トランザクション・コーディネータによって調整されるグローバル・トランザクションを使用します。これらのシステムはすべて、X/Open XAプロトコルを使用して、データベースまたは他のリソースごとにXAリソース・マネージャ(RM)によって提供される標準APIを使用して、2フェーズ・コミット・プロセスを編成します。Oracle Blockchain Platformは、2フェーズ・コミットをサポートし、外部トランザクション・コーディネータがXA準拠APIの起動に使用できる独自のXA RMライブラリを提供します。これらのグローバル・トランザクションには、最後のリソース・コミット最適化を使用して、単一の非XAリソース(Oracle以外のブロックチェーン・レジャーまたは非XA準拠データベースなど)を含めることもできます。

XA仕様は、X/Open分散トランザクション処理アーキテクチャの一部であり、複数のアプリケーション・プログラムが複数のリソース・マネージャから提供されるリソースを共有できるようにするための標準アーキテクチャを定義します。Java XAインタフェース自体は、Javaプラットフォームの一部として定義されます。Java XAインタフェースの詳細は、JavaドキュメントのインタフェースXAResourceを参照してください。

Oracle Blockchain Platformは、XA仕様に準拠し、XAリソース・マネージャ用の標準Javaインタフェースを実装するライブラリを提供します。ライブラリを使用すると、クライアント側のトランザクションマネージャーがグローバルトランザクションを調整できます。グローバル・トランザクションは、データベース更新やブロックチェーン・トランザクションなどの操作を含む可能性のある単一の作業単位であり、これらはすべて原子的にコミットする必要があります。つまり、すべての操作を正常にコミットする必要があります。グローバル・トランザクションの一部である操作が失敗すると、すべての操作がロールバックされます。XAインタフェースは、アトミック・トランザクションのRESTエンドポイントでサポートされるプロトコルと同様に、2フェーズ・コミット・プロトコルに依存します。Oracle Blockchain Platformのアトミック・トランザクションの詳細は、チェーンコードおよびチャネル間でのアトミック更新を参照してください。

Oracle Blockchain PlatformのXA実装は、Javaライブラリとして提供され、Oracle Blockchain Platformコンソールの「アプリケーション開発」ペインの「開発者ツール」タブからダウンロードできます。

ライブラリの詳細は、ダウンロード可能なファイルに用意されているJavadoc情報に含まれています。ライブラリでサポートされる3つのキー・オブジェクトは、OBPXAResourceOBPXADataSourceおよびOBPXAConnectionです。
オブジェクト 目 的
OBPXAResource このクラスは、トランザクション・マネージャがXAトランザクションのリソース・マネージャとしてOracle Blockchain Platformと連携するために必要なAPIを実装します。
OBPXADataSource このオブジェクトを使用して、OBPXAConnectionのインスタンスを取得し、認証および認可資格証明を指定します。
OBPXAConnection このオブジェクトを使用して、OBPXAResourceオブジェクトのインスタンスを取得し、XAトランザクションの一部として実行するブロックチェーン・トランザクションを定義します。

XAライブラリをOracle Blockchain Platformとともに使用するには、アプリケーションは、リクエストされた操作の認証および認可のための資格証明を提供する必要があります。ライブラリでは、基本認証(ユーザー/パスワード)とOAuth 2.0の両方のアクセス・トークンがサポートされており、OBPXADataSourceインスタンスの作成時に構成できます。2つの認証方法は、Oracle Blockchain Platform RESTプロキシで使用する認証方法と一致しています。詳細は、REST APIドキュメントの認証を参照してください。

OBPXADataSourceインスタンスを作成した後、obpxaDataSource.getXAConnection()メソッドを使用してxaConnectionインスタンスを取得できます。OAuth 2.0アクセス・トークンを使用しているときに認証を更新するには、次のコードに示すように、getXAConnectionメソッドを使用できます。
OBPXAConnection xaConnection = obpxaDataSource.getXAConnection(accessToken);      // get an XA connection using an OAuth 2.0 access token
getXAConnectionメソッドを使用して、基本認証を更新することもできます。
OBPXAConnection xaConnection = obpxaDataSource.getXAConnection(user, password);   // get an XA connection using username and password for basic authentication
グローバルXAトランザクションの一部として実行されるブロックチェーン・トランザクションを定義するには、次の方法を使用します。
public void createXAInvokeTransaction​(Xid xid, OBPXAInvokeTxRequest invokeTxRequest)
このメソッドでは、xidはグローバル・トランザクション識別子で、invokeTxRequestはグローバルXAトランザクションの一部として実行されるブロックチェーン・トランザクションです。XA呼出しトランザクション・リクエストを作成するには、次のコンストラクタ・メソッドを使用します。
OBPXAInvokeTxRequest invokeTxRequest = new OBPXAInvokeTxRequest(channel, chaincode, args);
このコンストラクタ・メソッドでは、channelはブロックチェーン・トランザクションが実行されるチャネル、chaincodeは使用するチェーンコード、argsにはチェーンコード関数およびトランザクションに使用する引数が含まれます。

次のコード・スニペットは、OBPXADataSourceオブジェクトの作成、OBPXAConnectionインスタンスの取得、トランザクション・リクエストの作成、および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);

シナリオ: サンプルを使用したXAトランザクションの参照

シナリオ: サンプルを使用した原子性トランザクションの探索(Oracle Blockchain Platformに付属している残高転送サンプルとMarblesサンプルを使用する)のシナリオは、原子性トランザクションに類似しています。

このシナリオでは、残高転送サンプルとMarblesサンプルをOracle Blockchain Platformの2つの異なるインスタンスにインストールします。その後、各インスタンスはXAデータ・ソースに対応します。

  • 商品チャネルにMarblesチェーンコードがインストールされたXAリソースOBP-1
  • ウォレット・チャネルに残高転送チェーンコードがインストールされているXAリソースOBP-2

このシナリオでは、複数のデータ・ソースにまたがるXAトランザクションを使用して、資金の交換と大理石の転送が原子的な方法で行われるようにし、すべての操作が成功するか、成功しないかを保証できます。次のコードは、このシナリオを説明します。

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

MarblesサンプルおよびMarble Ownerフィールドのデフォルト値に既知の問題があります。詳細は、Oracle Blockchain Platformの既知の問題を参照してください。