后浪云OceanBase教程: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;
}
}