在全球分布式事务处理中包括 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 Distributed Transaction Processing 体系结构的一部分,该体系结构定义了一个标准体系结构,使多个应用程序能够共享由多个资源管理器提供的资源。Java XA 接口本身被定义为 Java 平台的一部分。有关 Java XA 接口的更多信息,请参见 Java 文档中的 Interface XAResource

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

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

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

要将 XA 库与 Oracle Blockchain Platform 一起使用,应用程序必须提供用于验证和授权所请求操作的身份证明。该库支持基本验证(用户/密码)和 OAuth 2.0 访问令牌,您可以在创建 OBPXADataSource 实例时配置这些令牌。这两种验证方法与您与 Oracle Blockchain Platform REST 代理使用的验证方法一致。您可以使用基本验证进行测试和内部开发。请勿在生产环境中使用基本验证。有关更多信息,请参见 REST API 文档中的 Authentication

创建 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 的两个不同实例上安装 Balance Transfer 和 Marbles 样例。然后,每个实例对应于一个 XA 数据源:

  • XA 资源 OBP-1,在 goods 通道上安装了 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