13.3 シャーディングされたデータベースへの透過的アクセス用のシャーディング・データ・ソース
Oracle Databaseリリース21cでは、アプリケーションがシャーディング・キーを提供する必要なくシャード・データベースへのJava接続を可能にする、新しいJDBCデータ・ソースが導入されました。
シャード・データ・ソースを使用する場合、前の「シャーディング・キーを使用したプールからの接続のチェックアウト方法」の項で説明したように、シャード・データベースへの接続を確立するために、シャーディング・キーとスーパー・シャーディング・キーを識別したり、作成する必要はありません。シャーディング・データ・ソースでは、複数のシャード問合せ用に別のデータ・ソースを保持する必要もありません。
接続プロパティoracle.jdbc.useShardingDriverConnection
をtrue
に設定すると、このデータ・ソースはシャード・データベースに透過的にスケール・アウトされます。
次の表に、シャード・データ・ソースの使用方法を示します:
例13-2 シャーディング・データ・ソースの使用
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import oracle.jdbc.internal.OracleConnection;
import oracle.ucp.jdbc.PoolDataSource;
import oracle.ucp.jdbc.PoolDataSourceFactory;
public class ShardingDataSourceUCP {
public static void main(String[] args) throws SQLException {
ShardingDataSourceUCP sample = new ShardingDataSourceUCP();
DataSource ucpDataSource = sample.getDataSource();
// Get the details of following customers
int[] customerIds = new int[] {
100,
101,
102,
103,
104,
105
};
for (int id: customerIds) {
try (Connection conn = ucpDataSource.getConnection()) {
sample.displayCustomerDetails(conn, id);
System.out.println(((OracleConnection) conn).getPercentageQueryExecutionOnDirectShard());
}
}
}
private void displayCustomerDetails(Connection conn, int id) throws SQLException {
try (PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM CUSTOMER where ID = ?")) {
pstmt.setInt(1, id);
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
// Print the customer details
}
}
}
}
private DataSource getDataSource() throws SQLException {
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource();
pds.setURL("<gsmURL>");
pds.setUser("<userName>");
pds.setPassword("<password>");
pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
Properties prop = new Properties();
// Connection property to enable sharding datasource feature, when this property
// is set you don't need to pass sharding key to UCP pool while borrowing the connection
prop.setProperty(OracleConnection.CONNECTION_PROPERTY_USE_SHARDING_DRIVER_CONNECTION, "true");
pds.setConnectionProperties(prop);
return pds;
}
}
13.3.1 単一のシャード・トランザクションのサポート
シャーディング・データ・ソースを使用すると、トランザクションを1つのシャードに制限できます。
単一のシャード・トランザクションのサポートを有効にするには、CONNECTION_PROPERTY_ALLOW_SINGLE_SHARD_TRANSACTION_SUPPORT
を設定する必要があります。このプロパティが設定されていない場合、デフォルトでは、すべてのトランザクションがシャード・カタログで起動されます。このプロパティの値をtrue
に設定した場合、すべてのトランザクションが1つのシャードにのみまたがることを確認する必要があります。
例13-3 単一シャード・トランザクションの有効化
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import oracle.jdbc.internal.OracleConnection;
import oracle.jdbc.pool.OracleDataSource;
public class SingleShardTransactionUCP {
public static void main(String[] args) throws SQLException {
SingleShardTransactionUCP sample = new SingleShardTransactionUCP();
DataSource ucpDS = sample.getDataSource();
// Insert and update the details of following customers in a single transaction
int[] customerIds = new int[] {
100,
101,
102,
103,
104,
105
};
for (int id: customerIds) {
try (Connection conn = ucpDS.getConnection()) {
conn.setAutoCommit(false);
sample.insertCustomerDetails(conn, id);
sample.displayCustomerDetails(conn, id);
sample.updateCustomerDetails(conn, id);
sample.displayCustomerDetails(conn, id);
conn.commit();
System.out.println(((OracleConnection) conn).getPercentageQueryExecutionOnDirectShard());
}
}
}
private void insertCustomerDetails(Connection conn, int id) throws SQLException {
String sql = "insert into CUSTOMER values(?, ?, ?, ?)";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, id);
ps.setString(2, name);
ps.setString(3, email);
ps.setString(4, phoneNumber);
ps.executeUpdate();
}
}
private void updateCustomerDetails(Connection conn, int id) throws SQLException {
String sql = "UPDATE CUSTOMER SET name = ?, email = ?, phoneNumber = ? WHERE customerId = ?";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, name);
ps.setString(2, email);
ps.setString(3, phoneNumber);
ps.setInt(4, id);
ps.executeUpdate();
}
}
private void displayCustomerDetails(Connection conn, int id) throws SQLException {
try (PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM CUSTOMER where ID = ?")) {
pstmt.setInt(1, id);
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
//Print the customer details
}
}
}
}
private DataSource getDataSource() throws SQLException {
OracleDataSource ds = new OracleDataSource();
ds.setURL( < gsmURL > );
ds.setUser( < userName > );
ds.setPassword( < password > );
Properties prop = new Properties();
//Connection property to enable sharding datasource feature
prop.setProperty(OracleConnection.CONNECTION_PROPERTY_USE_SHARDING_DRIVER_CONNECTION, "true");
//Connection property to enable single shard transaction support. If this property is not set,
// by default all the transactions are started on catalog DB. When setting this property value
// to "true", applications must ensure that all the transactions span over a single shard only.
prop.setProperty(oracle.jdbc.OracleConnection.CONNECTION_PROPERTY_ALLOW_SINGLE_SHARD_TRANSACTION_SUPPORT, "true");
ds.setConnectionProperties(prop);
return ds;
}
}