在全球分布式事务中包括 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 来编排两阶段提交流程。Oracle Blockchain Platform 支持两阶段提交,并提供自己的 XA RM 库,外部事务协调员可以使用该库调用符合 XA 的 API。通过使用上次资源提交优化,这些全局事务处理还可以包括单个非 XA 资源(例如,非 Oracle 区块链分类账或不符合 XA 的数据库)。

XA 规范是 X/Open 分布式事务处理体系结构的一部分,该体系结构定义了一个标准体系结构,使多个应用程序能够共享多个资源管理器提供的资源。Java XA 接口本身被定义为 Java 平台的一部分。有关 Java XA 接口的详细信息,请参阅 Java 文档中的接口 XAResource

Oracle Blockchain Platform 提供了一个符合 XA 规范的库,并为 XA 资源管理器实施标准 Java 接口。通过该库,客户端事务处理管理器可以协调全局事务处理。全局事务处理是单个工作单元,可能包括数据库更新和区块链事务处理等操作,所有这些操作都必须以原子方式提交。换言之,所有操作都必须成功提交。如果属于全局事务处理的任何操作失败,则将回退所有操作。XA 接口依赖于两阶段提交协议,类似于原子事务处理 REST 端点支持的协议。有关 Oracle Blockchain Platform 中原子事务处理的详细信息,请参阅跨链代码和渠道进行原子更新

Oracle Blockchain Platform 的 XA 实施以 Java 库的形式提供,可从 Oracle Blockchain Platform 控制台的应用程序开发窗格上的开发人员工具选项卡下载。

有关库的完整详细信息包含在可下载文件中提供的 Javadoc 信息中。库支持的三个关键对象为 OBPXAResourceOBPXADataSourceOBPXAConnection
对象 用途
OBPXAResource 此类为事务处理管理器实施所需的 API,以便与 Oracle Blockchain Platform 作为 XA 事务处理的资源管理器协调。
OBPXADataSource 使用此对象可获取 OBPXAConnection 的实例并指定验证和授权身份证明。
OBPXAConnection 使用此对象可获取 OBPXAResource 对象的实例并定义要作为 XA 事务处理的一部分运行的区块链事务处理。

要将 XA 库与 Oracle Blockchain Platform 一起使用,应用程序必须提供身份证明,以便对请求的操作进行验证和授权。该库支持基本验证(用户/密码)和 OAuth 2.0 访问令牌,您可以在创建 OBPXADataSource 实例时配置这些令牌。这两种验证方法与您与 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 中包含的余额转移和大理石样本。

在此方案中,您可以在 Oracle Blockchain Platform 的两个不同实例上安装余额转移和大理石示例。然后,每个实例对应于一个 XA 数据源:

  • XA 资源 OBP-1,在商品渠道上安装了 Marbles 链代码
  • XA 资源 OBP-2,在 wallet 通道上安装了余额转移链代码

在这种情况下,您可以使用跨多个数据源的 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

大理石样本和大理石所有者字段的默认值存在已知问题。有关详细信息,请参阅:Oracle Blockchain Platform 的已知问题