この項では、OracleConnectionプロバイダ固有の機能について説明します。項目は次のとおりです。
表3-1は、サポートされている接続文字列属性のリストです。
表3-1 サポートされている接続文字列属性
| 接続文字列属性 | デフォルト値 | 説明 |
|---|---|---|
|
|
|
接続の最大存続期間(秒)。 |
|
|
|
プールから使用可能な接続を待機する最大時間(秒)。 |
|
|
|
.NETストアド・プロシージャでのみサポートされています。 |
|
|
空の文字列 |
接続するデータベースを識別するOracle Netサービス名、接続記述子または簡易接続ネーミング。 |
|
|
空の文字列 |
管理者権限: |
|
|
|
未使用の確立済接続量が過剰となり、クローズされる接続数。 |
|
|
|
COM+トランザクションまたは |
|
|
|
RACサービス、サービス・メンバーまたはノードが停止した場合、ODP.NET接続プールが予防的にプールから接続を削除できるようにします。 |
|
|
|
ODP.NET接続プールを使用して、ロード・バランシングおよびサービス目標に基づき、RACインスタンス間の作業要求のバランスを調整できます。 |
|
|
|
プール内のすべての接続が使用された場合に作成される新しい接続の数。 |
|
|
|
プール内の接続の最大数。 |
|
|
|
メタデータ情報をキャッシュします。 |
|
|
|
プール内の接続の最小数。 |
|
|
空の文字列 |
|
|
|
|
接続文字列でのパスワード検索。 |
|
|
|
接続プーリング。 |
|
|
空の文字列 |
プロキシ・ユーザーのユーザー名。 |
|
|
空の文字列 |
プロキシ・ユーザーのパスワード。 |
|
|
|
接続がプールに戻るときの文キャッシュの消去。 |
|
|
|
文キャッシングの有効化と、キャッシュ・サイズ、つまりキャッシュ可能な文の最大数。 |
|
|
空の文字列 |
Oracleユーザー名。 |
|
|
|
プールから発生した接続の検証。 |
次の例は、Oracleデータベースへの接続に接続文字列属性を使用します。
// C#
using System;
using Oracle.DataAccess.Client;
class ConnectionSample
{
static void Main()
{
OracleConnection con = new OracleConnection();
//using connection string attributes to connect to Oracle Database
con.ConnectionString = "User Id=scott;Password=tiger;Data Source=oracle";
con.Open();
Console.WriteLine("Connected to Oracle" + con.ServerVersion);
// Close and Dispose OracleConnection object
con.Close();
con.Dispose();
Console.WriteLine("Disconnected");
}
}
この項では、データ・ソース属性を指定する複数の方法について説明します。
次の例は、tnsnames.oraファイル内のsalesというTNS別名にマップされた接続記述子を示しています。
sales=
(DESCRIPTION=
(ADDRESS= (PROTOCOL=tcp)(HOST=sales-server)(PORT=1521))
(CONNECT_DATA=
(SERVICE_NAME=sales.us.acme.com)))
TNS別名を使用してscott/tigerとして接続するには、有効な接続は次のようになります。
"user id=scott;password=tiger;data source=sales";
ODP.NETでは、アプリケーションはtnsnames.oraファイルを使用せずに接続することもできます。そのためには、接続記述子全体を"data source"として使用できます。
接続文字列は次のようになります。
"user id=scott;password=tiger;data source=" +
"(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)" +
"(HOST=sales-server)(PORT=1521))(CONNECT_DATA="+
"(SERVICE_NAME=sales.us.acme.com)))"
簡易接続ネーミング・メソッドを使用すると、クライアントは構成を行わずにデータベースに接続できます。
簡易接続ネーミング・メソッドを使用する前に、sqlnet.oraファイルのNAMES.DIRECTORY_PATHパラメータにより、EZCONNECTが次のように指定されていることを確認します。
NAMES.DIRECTORY_PATH= (TNSNAMES, EZCONNECT)
これが有効になっていると、ODP.NETにより、アプリケーションでは"Data Source"属性を次の書式で指定できます。
//host:[port]/[service_name]
同じ例を使用して、有効な接続文字列を次に示します。
"user id=scott;password=tiger;data source=//sales-server:1521/sales.us.acme.com" "user id=scott;password=tiger;data source=//sales-server/sales.us.acme.com" "user id=scott;password=tiger;data source=sales-server/sales.us.acme.com"
ポート番号が指定されていない場合、デフォルトで1521が使用されます。
ODP.NET接続プーリングは、Pooling接続文字列属性を使用して有効化または無効化できます。デフォルトでは、接続プーリングは有効です。次に、接続プーリング・サービスの動作を制御するConnectionString属性を示します。
Connection Lifetime
Connection Timeout
Decr Pool Size
HA Events
Incr Pool Size
Load Balancing
Max Pool Size
Min Pool Size
Pooling
Validate Connection
次の例は、接続プーリングに関連するConnectionString属性を使用して、接続をオープンします。
// C#
using System;
using Oracle.DataAccess.Client;
class ConnectionPoolingSample
{
static void Main()
{
OracleConnection con = new OracleConnection();
//Open a connection using ConnectionString attributes
//related to connection pooling.
con.ConnectionString =
"User Id=scott;Password=tiger;Data Source=oracle;" +
"Min Pool Size=10;Connection Lifetime=120;Connection Timeout=60;" +
"Incr Pool Size=5; Decr Pool Size=2";
con.Open();
Console.WriteLine("Connection pool successfully created");
// Close and Dispose OracleConnection object
con.Close();
con.Dispose();
Console.WriteLine("Connection is placed back into the pool.");
}
}
接続プーリングが有効な場合(デフォルト)、OracleConnectionオブジェクトのOpenおよびCloseメソッドは、接続プーリング・サービスを暗黙的に使用します。これは、接続をプールしてアプリケーションに戻す処理を担当します。
接続プーリング・サービスは、プールを一意に識別するために、ConnectionStringプロパティを署名として使用して接続プールを作成します。
ConnectionStringプロパティの正確な属性値を持つプールが存在しない場合、接続プーリング・サービスは新しい接続プールを作成します。要求された署名を持つプールがすでに存在する場合、接続はそのプールからアプリケーションに戻されます。
接続プールが作成されると、接続プーリング・サービスは、ConnectionStringのMin Pool Size属性で定義された接続数を最初に作成します。この接続数は、接続プールの接続プーリング・サービスによって常に保持されます。
これらの接続は、常にアプリケーションで使用され、またプール内でも使用できます。
ConnectionStringプロパティのIncr Pool Size属性には、接続プールでより多くの接続が必要になったときに、接続プーリング・サービスで作成される新しい接続の数を定義します。
アプリケーションが接続をクローズすると、接続プーリング・サービスは、接続存続期間がConnection Lifetime属性を超えているかどうかを調べます。超えている場合、接続プーリング・サービスは接続をクローズし、超えていない場合、接続は接続プールに戻ります。接続プーリング・サービスは、接続が接続プールに戻るときのみ、Connection Lifetimeを実行します。
ConnectionStringプロパティのMax Pool Size属性は、接続プールの接続の最大数を設定します。新しい接続が要求されたときに、有効な接続がなく、Max Pool Sizeに達している場合、接続プーリング・サービスは、Connection Timeout属性で定義された時間待機します。Connection Timeoutに達していても、プールに有効な接続がない場合、接続プーリング・サービスは、接続プール要求がタイムアウトしたことを示す例外を呼び出します。
Validate Connection属性は、プールから発生する接続を検証します。この属性は、必要な場合にのみ使用してください。この属性により、データベースへのラウンドトリップが、各接続権をアプリケーションに付与する前に検証するためです。無効な接続が特殊な場合、開発者はValidate Connection属性を使用するのではなく、独自のイベント・ハンドラを作成して、新しい接続を取得および検証できます。通常は、これによりパフォーマンスが改善されます。
接続が使用されていない場合、接続プーリング・サービスは接続をクローズします。接続は3分ごとにクローズされます。ConnectionStringプロパティのDecr Pool Size属性は、接続プーリング・サービスに対して、3分ごとにクローズできる接続の最大数を指定します。
ODP.NET接続プールの管理では、ODP.NETアプリケーションが接続プールを明示的に管理できます。 アプリケーションは、接続プール内の接続を明示的に消去できます。
接続プール管理を使用して、アプリケーションは次の処理を実行できます。
ClearPoolメソッドを使用して接続プールから接続を消去します。
ClearAllPoolsメソッドを使用して、アプリケーション・ドメイン内のすべての接続プールに含まれる接続を消去します。
この項では、Real Application Clusters(RAC)データベースでの接続プーリングの最適化およびその他の側面について説明します。RACとは、1つのクラスタ内の複数ノードで実行されている複数のインスタンスからデータベースにアクセスできる機能を提供することにより、Oracleデータベースでグリッド化を可能にするテクノロジです。
Oracle Data Provider for .NETは、ロード・バランシングおよびサービス目標に基づいて、RACインスタンス間の作業要求のバランスを調整することにより、RACデータベースの接続プーリングを最適化します。さらに、ODP.NET接続プールを有効にすることで、RACサービス、サービス・メンバーまたはノードの停止により切断された接続に関連付けられているリソースを事前に解放できます。
Oracle Data Provider for .NETでは、RACでの接続プーリングを最適化するために次の機能が使用されます。
実行時の接続ロード・バランシング
実行時の接続ロード・バランシング属性を有効にした場合:
ODP.NET接続プールでは、ロード・バランシングおよびサービス目標に基づき、接続を分配します。
また、ODP.NET接続プールは、ロード・バランシングおよびサービス目標に基づき、サービスを提供する各サービス・メンバーに対して接続数のバランスを調整します。
デフォルトでは、この機能は無効です。 実行時の接続ロード・バランシングを有効化するには、接続文字列に、"Load Balancing=true"を含めます。 この機能は、"pooling=true"の場合にかぎり、RACデータベースに対してのみ使用できます。
実行時の接続ロード・バランシングを使用するには、特定のRACを構成する必要があります。 詳細は、『Oracle Database Oracle ClusterwareおよびOracle Real Application Clusters管理およびデプロイメント・ガイド』を参照してください。Oracle Net Servicesに対してロード・バランシングの構成をする必要があります。 詳細は、『Oracle Net Services管理者ガイド』を参照してください。
次の例は、実行時の接続ロード・バランシングを有効にする接続文字列です。
"user id=scott;password=tiger;data source=erp;load balancing=true;"
HAイベント
HAイベントを有効にした場合:
ODP.NET接続プールでは、RACサービス、サービス・メンバーまたはノードの停止時に、プールから接続を事前に削除します。
切断された接続を削除して、接続合計数が"min pool size"を下回った場合、ODP.NETは既存のRACインスタンスへの接続を確立します。
デフォルトでは、この機能は無効です。 この機能を有効にするには、接続文字列に"HA Events=true"を含めます。 この機能は、"pooling=true"の場合にかぎり、RACデータベースに対してのみ使用できます。
次の例は、HAイベントを有効にする接続文字列です。
"user id=scott;password=tiger;data source=erp;HA events=true;"
非RACデータベースに対して接続プールが作成された場合、プール・サイズ属性は単一のサービスに適用されます。同様に、RACデータベースに対して接続プールが作成された場合、プール・サイズ属性はサービスに適用され、サービス・メンバーには適用されません。たとえば、"Min Pool Size"がNに設定されている場合、ODP.NETでは各サービス・メンバーに対してN個の接続を作成しません。かわりに、サービス全体に対して最小N個の接続を作成します。この場合、サービス・メンバー間でN個の接続が分散されます。
次のプール・サイズ接続文字列属性が、サービスに適用されます。
Min Pool Size
Max Pool Size
Incr Pool Size
Decr Pool Size
Oracleデータベースは、Windowsのユーザー・ログイン資格証明を使用してデータベース・ユーザーを認証できます。Windowsのユーザー・ログイン資格証明を使用して接続をオープンするには、User Id ConnectionString属性をスラッシュ(/)に設定する必要があります。Password属性を指定しても無視されます。
|
注意: オペレーティング・システム認証は、.NETストアド・プロシージャではサポートされません。 |
オペレーティング・システム認証の使用例を次に示します。
/* Create an OS-authenticated user in the database
Assume init.ora has OS_AUTHENT_PREFIX set to "" and <OS_USER>
is any valid OS or DOMAIN user.
create user <OS_USER> identified externally;
grant connect, resource to <OS_USER>;
Login through OS Authentication and execute the sample. See Oracle
documentation for details on how to configure an OS-Authenticated user
*/
// C#
using System;
using Oracle.DataAccess.Client;
class OSAuthenticationSample
{
static void Main()
{
OracleConnection con = new OracleConnection();
//Establish connection using OS Authentication
con.ConnectionString = "User Id=/;Data Source=oracle;";
con.Open();
Console.WriteLine("Connected to Oracle" + con.ServerVersion);
// Close and Dispose OracleConnection object
con.Close();
con.Dispose();
Console.WriteLine("Disconnected");
}
}
データベース管理者は、SYSDBAまたはSYSOPER権限を使用してOracleデータベースにアクセスできます。これは、ConnectionStringプロパティのDBA Privilege属性によって実行されます。
次の例では、SYSDBAとしてscott/tigerに接続します。
// C#
using System;
using Oracle.DataAccess.Client;
class PrivilegedConnectionSample
{
static void Main()
{
OracleConnection con = new OracleConnection();
//Connect scott/tiger as SYSDBA
con.ConnectionString = "User Id=scott;Password=tiger;" +
"DBA Privilege=SYSDBA;Data Source=oracle;";
con.Open();
Console.WriteLine("Connected to Oracle" + con.ServerVersion);
// Close and Dispose OracleConnection object
con.Close();
con.Dispose();
Console.WriteLine("Disconnected");
}
}
ユーザーのパスワードを失効させることができます。ODP.NETは、新しいパスワードで接続をオープンする新しいメソッドOpenWithNewPasswordを指定することで、アプリケーションにパスワードの失効を処理させることができます。
次のコードは、pantherの新しいパスワードで接続するために、OracleConnection OpenWithNewPasswordメソッドを使用しています。
/* Database Setup
connect / as sysdba;
drop user testexpire cascade;
-- create user "testexpire" with password "testexpire"
grant connect , resource to testexpire identified by testexpire;
alter user testexpire password expire;
*/
// C#
using System;
using Oracle.DataAccess.Client;
class PasswordExpirationSample
{
static void Main()
{
OracleConnection con = new OracleConnection();
try
{
con.ConnectionString =
"User Id=testexpire;Password=testexpire;Data Source=oracle";
con.Open();
Console.WriteLine("Connected to Oracle" + con.ServerVersion);
}
catch (OracleException ex)
{
Console.WriteLine(ex.Message);
//check the error number
//ORA-28001 : the password has expired
if (ex.Number == 28001)
{
Console.WriteLine("\nChanging password to panther");
con.OpenWithNewPassword("panther");
Console.WriteLine("Connected with new password.");
}
}
finally
{
// Close and Dispose OracleConnection object
con.Close();
con.Dispose();
Console.WriteLine("Disconnected");
}
}
}
|
注意: OpenWithNewPasswordは、パスワードを変更するためではなく、ユーザーのパスワードが失効した場合のみ使用してください。 |
データベースの設定が正しければ、データベース・ユーザーの識別情報および特権を保持し、ユーザーのかわりに監査処理を実行して、プロキシ認証により、中間層アプリケーションでセキュリティを制御できるようになります。 そのためには、(実在の)データベース・ユーザー(複数可)のかわりにデータベースに接続し、認証を受けるプロキシ・データベース・ユーザーを作成および使用します。
プロキシ認証は、接続プーリングのスケーラビリティを強化する目的でも使用できます。 接続プーリングをプロキシ認証と組み合せて使用すると、プロキシ認証済の接続を、実在する複数のユーザーで共有できます。これは、プロキシに対して確立済の接続およびセッションのみがキャッシュされるためです。プロキシ認証済の接続を要求すると、セッションが実際のユーザーに対して追加作成されますが、このプロキシ認証済接続がプール内に戻されると、追加作成されたセッションは廃棄されます。この設計により、セキュリティを犠牲にすることなくアプリケーションのスケーラビリティを強化できます。
ODP.NETアプリケーションでプロキシ認証を使用するには、接続文字列に、"Proxy User Id"属性および"Proxy Password"属性を設定します。実在のユーザーは、"User Id"属性で指定します。オプションで、"Password"接続文字列属性を介して実在のユーザーのパスワードを指定すると、セキュリティがさらに強化されます。
ODP.NETプロキシ認証の使用例を次に示します。
/* Log on as DBA (SYS or SYSTEM) that has CREATE USER privilege.
Create a proxy user and modified scott to allow proxy connection.
create user appserver identified by eagle;
grant connect, resource to appserver;
alter user scott grant connect through appserver;
*/
// C#
using System;
using Oracle.DataAccess.Client;
class ProxyAuthenticationSample
{
static void Main()
{
OracleConnection con = new OracleConnection();
// Connecting using proxy authentication
con.ConnectionString = "User Id=scott;Password=tiger;" +
"Data Source=oracle;Proxy User Id=appserver;Proxy Password=eagle; ";
con.Open();
Console.WriteLine("Connected to Oracle" + con.ServerVersion);
// Close and Dispose OracleConnection object
con.Close();
con.Dispose();
Console.WriteLine("Disconnected");
}
}
OracleConnectionオブジェクトのEnlistDistributedTransactionメソッドまたはEnlistTransactionメソッドにより分散トランザクションに動的に登録されるアプリケーションの場合、"enlist"接続文字列属性を"dynamic"または"true"のいずれかの値に設定する必要があります。 "enlist=true"の場合、OpenメソッドがOracleConnectionオブジェクトでコールされると、このメソッドがCOM+トランザクションまたはSystem.Transactionsのコンテキスト内にあれば、接続がトランザクションに登録されます。 それ以外の場合、OracleConnectionオブジェクトは分散トランザクションに登録されませんが、後でEnlistDistributedTransactionメソッドまたはEnlistTransactionメソッドを使用して明示的に登録できます。 "enlist=false"の場合、接続はトランザクションに登録できません。
"Enlist=dynamic"を使用して再構築できないアプリケーションの場合、REG_SZタイプのレジストリ文字列値DynamicEnlistmentを、HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\ODP.NET\Assembly_Versionの下に作成できます。ここでは、Assembly_VersionはOracle.DataAccess.dllの完全なアセンブリ・バージョン番号です。 ODP.NETが正しくインストールされている場合、StatementCacheSize、TraceFileNameなどの値名がすでに同じODP.NETキーの下に存在する必要があります。 DynamicEnlistmentレジストリ・キーが0に設定されているか、またはレジストリ・エントリが存在しない場合、アプリケーションには影響しません。 ただし、DynamicEnlistmentが1に設定されている場合、"Enlist=false"は"Enlist=dynamic"と同じ扱いとなり、アプリケーションはコードを変更せずにEnlistDistributedTransactionメソッドを使用して正常に登録できます。 DynamicEnlistmentを1に設定しても、接続文字列に"Enlist=true"または"Enlist=dynamic"が含まれるOracleConnectionオブジェクトには影響しません。
クライアント識別子は、Oracleアプリケーションのコンテキスト・ネームスペースUSERENVから事前に定義された属性です。ユーザー識別情報のトラッキングが可能であるという点で、プロキシ認証に似ています。ただし、プロキシ認証では、2つのセッション(プロキシ・ユーザー用とエンド・ユーザー用)を作成する必要がありません。さらに、クライアント識別子は、データベース・ユーザーである必要はありません。任意の文字列に設定できます。最も重要な点は、クライアント識別子を使用することで、ODP.NET開発者がApplication ContextおよびOracle Label Securityを使用してOracle Virtual Private Database(VPD)をより簡単に構成できることです。クライアント識別子を設定するため、接続をオープンしてから、ODP.NETアプリケーションでOracleConnectionオブジェクトにClientIdプロパティを設定できます。接続プーリングが有効な場合、プールに接続が戻されると、常にClientIdはnullにリセットされます。
ODP.NETは、OracleConnectionオブジェクト上でClientIdプロパティを公開します。 ClientIdプロパティを内部で設定することでCLIENT_IDENTIFIER属性がセッション上に設定されます。ClientIdプロパティを消去するには、単にこれを""またはstring.Emptyに設定します。ClientIdプロパティは書込み専用です。
透過的アプリケーション・フェイルオーバー(TAF)は、高可用性を提供するOracleデータベースの機能です。
|
注意: TAFは、.NETストアド・プロシージャではサポートされません。 |
TAFを使用すると、接続が継続していれば、別のデータベース・インスタンスに自動的に再接続できます。アクティブなトランザクションはロールバックされますが、別のノードを経由した新しいデータベース接続は、元の接続と同一です。これは、接続が失敗した方法に関係なく当てはまります。
TAFを使用すると、アプリケーションを提供するインスタンスが1つ残っているかぎり、クライアントで接続が失われることはありません。データベース管理者は、インスタンスで実行されるアプリケーションを制御して、各アプリケーションのフェイルオーバー命令も作成します。
別のデータベースにセッションがフェイルオーバーした場合、元のセッションで最初に設定されていたNLS設定は、新しいセッションに引き継がれません。したがって、これらのNLS設定は、アプリケーション側で新しいセッションに設定する必要があります。
フェイルオーバーによる遅延を考慮して、アプリケーションではTAFコールバックによる通知を必要とします。ODP.NETは、OracleConnectionオブジェクトのFailoverイベントによるTAFコールバック機能をサポートしています。これにより、フェイルオーバーが発生したときは常にアプリケーションに通知されます。TAFコールバックを受信するには、Failoverイベントにイベント・ハンドラ関数を登録する必要があります。
フェイルオーバーが発生すると、Failoverイベントが発生し、別のOracleインスタンスに接続を再確立する過程で、イベント・ハンドラが複数回起動されます。
イベント・ハンドラの最初のコールは、Oracleデータベースがインスタンス接続の損失を最初に検出したときに行われます。これにより、アプリケーションはフェイルオーバーの次の遅延に応じて動作します。
フェイルオーバーが成功した場合、接続が再確立されて使用可能になったときにFailoverイベントが発生します。この時点で、アプリケーションはOracleGlobalizationセッション設定を再同期化して、フェイルオーバーが発生したことをアプリケーション・ユーザーに通知できます。
フェイルオーバーが失敗した場合、フェイルオーバーが発生しなかったことをアプリケーションに通知するために、Failoverイベントが発生します。
アプリケーションは、イベント・ハンドラに渡されるOracleFailoverEventArgsオブジェクトをチェックすることで、フェイルオーバーが成功したかどうかを判断できます。
次のコード例は、OnFailoverと呼ばれるイベント・ハンドラ・メソッドを登録します。
// C#
using System;
using Oracle.DataAccess.Client;
class TAFCallBackSample
{
public static FailoverReturnCode OnFailover(object sender,
OracleFailoverEventArgs eventArgs)
{
switch (eventArgs.FailoverEvent)
{
case FailoverEvent.Begin :
Console.WriteLine(
" \nFailover Begin - Failing Over ... Please standby \n");
Console.WriteLine(
" Failover type was found to be " + eventArgs.FailoverType);
break;
case FailoverEvent.Abort :
Console.WriteLine(" Failover aborted. Failover will not take place.\n");
break;
case FailoverEvent.End :
Console.WriteLine(" Failover ended ...resuming services\n");
break;
case FailoverEvent.Reauth :
Console.WriteLine(" Failed over user. Resuming services\n");
break;
case FailoverEvent.Error :
Console.WriteLine(" Failover error gotten. Sleeping...\n");
return FailoverReturnCode.Retry;
default :
Console.WriteLine("Bad Failover Event: %d.\n", eventArgs.FailoverEvent);
break;
}
return FailoverReturnCode.Success;
} /* OnFailover */
static void Main()
{
OracleConnection con = new OracleConnection();
con.ConnectionString = "User Id=scott;Password=tiger;Data Source=oracle;";
con.Open();
con.Failover += new OracleFailoverEventHandler(OnFailover);
Console.WriteLine("Event Handler is successfully registered");
// Close and Dispose OracleConnection object
con.Close();
con.Dispose();
}
}
Failoverイベントは、1つのイベント・ハンドラのみを起動します。Failoverイベントに複数のFailoverイベント・ハンドラが登録されていても、最後に登録されたイベント・ハンドラのみが起動されます。
|
注意: フェイルオーバーが有効な環境では、分散トランザクションはサポートされません。 |