OceanBase 分布式事务示例
本节主要介绍如何使用 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.*;
客户端和服务器软件包分别具有 OracleXADataSource
、OracleXAConnection
和 OracleXAResource
类的版本。 这三个类的抽象版本位于顶级 oracle.jdbc.xa
包中。
Oracle XA 代码示例
如下为 XA 事务的处理过程示例:
使用
XA START
启动 XA 事务,并将其置于ACTIVE
状态。对于处于
ACTIVE
状态的 XA 事务,执行构成该事务的 SQL 语句,然后执行XA END
语句。XA END
使事务置于IDLE
状态。对于处于
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
列出。
对于处于
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;
}
}