要件 : リクエストのテナント ID に基づいて、各テナントのデータをそれぞれの PDB に挿入するマルチテナント アプリケーションを作成します。つまり、各テナントまたは顧客は CDB に独自の PDB を持ち、すべての PDB は同じスキーマを持ち、リクエストのテナント ID に基づいてデータソースが選択され、データがその PDB に挿入されます。
スタック - スプリング ブート 2.3.0.RELEASE、Oracle 18c、接続プール - Oracle 共有ユニバーサル接続プール
UCP 接続:
<ucp-properties>
<connection-pool
connection-pool-name="pool1"
connection-factory-class-name="oracle.jdbc.pool.OracleDataSource"
url="jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(HOST=localhost)(PORT=1521)(PROTOCOL=tcp))(CONNECT_DATA=(SERVICE_NAME=orcl.accounts.intern)))"
user="C##commonuser"
password="commonuser"
initial-pool-size="10"
min-pool-size="5"
max-pool-size="20"
connection-repurpose-threshold="13"
sql-for-validate-connection="select 1 from dual"
shared="true"
>
<connection-property name="oracle.jdbc.ReadTimeout" value="2000"/>
<connection-property name="oracle.net.OUTBOUND_CONNECT_TIMEOUT" value="2000"/>
<data-source data-source-name="pdbcust1" service="pdbcust1.accounts.intern" user="cust1" password="password"/>
<data-source data-source-name="pdbcust2" service="pdbcust2.accounts.intern" user="cust2" password="password"/>
</connection-pool>
</ucp-properties>
Spring データソース構成クラス:
@Bean
public DataSource dataSource() throws SQLException {
System.setProperty("oracle.ucp.jdbc.xmlConfigFile", "file:/" + dbConfigProperties.getUcpConfigFile());
final AbstractRoutingDataSource dataSource = new MultitenantRoutingDataSource();
targetDataSources = new ConcurrentHashMap<>();
final PoolDataSource tenantDataSource1 = getTenantDataSource("pdbcust1", "cust1", "password");
final PoolDataSource tenantDataSource2 = getTenantDataSource("pdbcust2", "cust2", "password");
targetDataSources.put("pdbcust1", tenantDataSource1 );
targetDataSources.put("pdbcust2", tenantDataSource2 );
dataSource.setDefaultTargetDataSource(lTenantDataSource2);
lDataSource.setTargetDataSources(lTargetDataSources);
lDataSource.afterPropertiesSet();
return lDataSource;
}
private static PoolDataSource getTenantDataSource(final String tenantId, String username, String password) {
try {
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(tenantId);
Properties prop = new Properties();
// prop.setProperty("user", username);
// prop.setProperty("password", password);
//pds.reconfigureDataSource(prop);
return pds;
} catch (final Exception e) {
e.printStackTrace();
}
return null;
}
上記の構成は機能せず、テナント ID で要求を発行すると、次のエラーがスローされます。
java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:509) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:461) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1104) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:550) ~[ojdbc8-19.3.0.0.jar:19.3.0.
ただし、上記のクラスの次の行のコメントを外し、UCP ファイルからユーザー名とパスワードを削除すると、機能します。
prop.setProperty("user", username);
prop.setProperty("password", password);
pds.reconfigureDataSource(prop);
だから私の質問は:
- なぜこれが起こるのですか?
- UCP config xmls xsd にはユーザーとパスワードのフィールドがありますが、どのように使用しますか?
- このページでは、共有プールについて説明します https://docs.oracle.com/middleware/12213/wls/JDBCA/shared_pooling_ds.htm#JDBCA-GUID-4B7DA858-327E-4CEA-A68C-376792D4A466 これには次の行があります:「この共通ユーザーは存在する必要があります共有データ ソースに接続されているすべての PDB で "これはどういう意味ですか?