云数据库OceanBase入门教程 OceanBase 分布式事务示例

2024-02-26 开发教程 云数据库OceanBase入门教程 匿名 4

本节主要介绍如何使用 Oracle XA 功能实现分布式事务的示例。

Oracle XA 导入

使用 Oracle XA 功能必须导入以下内容:

import oracle.jdbc.xa.OracleXid;
import oracle.jdbc.xa.OracleXAException;
import oracle.jdbc.pool.*;
import oracle.jdbc.xa.client.*;
import javax.transaction.xa.*;

oracle.jdbc.pool软件包具有用于连接池功能的类,并将与 XA 相关的类作为子类。

或者,如果代码将在数据库内部运行并访问该数据库以进行 SQL 操作,则必须导入 oracle.jdbc.xa.server而不是 oracle.jdbc.xa.client。语法如下:

import oracle.jdbc.xa.server.*;

客户端和服务器软件包分别具有 OracleXADataSourceOracleXAConnectionOracleXAResource类的版本。 这三个类的抽象版本位于顶级 oracle.jdbc.xa包中。

Oracle XA 代码示例

如下为 XA 事务的处理过程示例:

  1. 使用 XA START启动 XA 事务,并将其置于 ACTIVE状态。

  2. 对于处于 ACTIVE状态的 XA 事务,执行构成该事务的 SQL 语句,然后执行 XA END语句。XA END使事务置于 IDLE状态。

  3. 对于处于 IDLE状态的 XA 事务,可以执行 XA PREPARE语句或 XA COMMIT ... ONE PHASE语句:

    • XA PREPARE将事务置于 PREPARED状态。此时的 XA RECOVER语句在其输出中包括事务的 xid值,因为 XA RECOVER会列出所有处于PREPARED状态的 XA 事务。

    • XA COMMIT ... ONE PHASE用于预备和提交事务。由于事务终止,xid值未由 XA RECOVER列出。

  4. 对于处于 PREPARED状态的 XA 事务,可以执行 XA COMMIT语句来提交和终止事务,或者执行 XA ROLLBACK来回滚和终止事务。

public static void initClass() throws SQLException {
createTable(tableName1, "c1 int,c2 int");
createTable(tableName2, "c1 int,c2 int");
createTable(tableName3, "c1 varchar(200)");
}
public void obOracleXAOne() throws Exception {
Assume.assumeTrue(sharedUsePrepare());
Connection conn = setConnection();
conn.createStatement().execute(" insert into " + tableName1 + " values(1,2)");
JDBC4MysqlXAConnection mysqlXAConnection = new JDBC4MysqlXAConnection(
(OceanBaseConnection) conn);
String gtridStr = "gtrid_test_wgs_ob_oracle_xa_one";
String bqualStr = "bqual_test_wgs_ob_oracle_xa_one";
Xid xid = new MysqlXid(gtridStr.getBytes(), bqualStr.getBytes(), 123);
try {
mysqlXAConnection.start(xid, XAResource.TMNOFLAGS);
PreparedStatement pstmt = null;
ResultSet rs = null;
pstmt = conn.prepareStatement("select c1 from " + tableName1);
rs = pstmt.executeQuery();
while (rs.next()) {
System.out.println(rs.getInt(1));
}
pstmt.close();
pstmt = conn.prepareStatement("insert into " + tableName1 + " (c1, c2) values(?, ?)");
pstmt.setInt(1, 12);
pstmt.setInt(2, 12);
pstmt.executeUpdate();
mysqlXAConnection.end(xid, XAResource.TMSUCCESS);
mysqlXAConnection.prepare(xid);
mysqlXAConnection.commit(xid, false);
} catch (Exception e) {
e.printStackTrace();
mysqlXAConnection.rollback(xid);
throw e;
}
}
public void obOracleXAOnePhase() throws Exception {
Assume.assumeTrue(sharedUsePrepare());
Connection conn = null;
conn = setConnection();
conn.createStatement().execute(" insert into " + tableName2 + " values(1,2)");
JDBC4MysqlXAConnection mysqlXAConnection = new JDBC4MysqlXAConnection(
(OceanBaseConnection) conn);
String gtridStr = "gtrid_test_wgs_ob_oracle_xa_one_phase";
String bqualStr = "bqual_test_wgs_ob_oracle_xa_one_phase";
Xid xid = new MysqlXid(gtridStr.getBytes(), bqualStr.getBytes(), 123);
try {
mysqlXAConnection.start(xid, XAResource.TMNOFLAGS);
// ps test
PreparedStatement pstmt = null;
ResultSet rs = null;
pstmt = conn.prepareStatement("select c1 from " + tableName2 + "");
rs = pstmt.executeQuery();
while (rs.next()) {
System.out.println(rs.getInt(1));
}
pstmt.close();
pstmt = conn.prepareStatement("insert into " + tableName2 + " (c1, c2) values(?, ?)");
pstmt.setInt(1, 12);
pstmt.setInt(2, 12);
pstmt.executeUpdate();
mysqlXAConnection.end(xid, XAResource.TMSUCCESS);
mysqlXAConnection.commit(xid, true);
} catch (Exception e) {
mysqlXAConnection.rollback(xid);
throw e;
}
}