在全球分布式事务处理中包括 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 控制台的 Application Development 窗格上的 Developer Tools 选项卡下载。
OBPXAResource、OBPXADataSource 和 OBPXAConnection。
| 对象 | 用途 |
|---|---|
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 authenticationpublic 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, 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