連載目次
検証環境
- Oracle Cloud利用
- Oracle Linux 7.7 (VM.Standard2.1)
- Python 3.6
- cx_Oracle 8.0
- Oracle Database 19.6 (DBCS HP, 2OCPU)
- Oracle Instant Client 18.5
概要
前回はcx_Oracle自身の持つクライアントサイドのコネクションプール(セッションプール)について解説しましたが、今回はサーバーサイドのコネクションプール機能であるDRCP(Database Resident Connection Pool、データベース常駐接続プーリング)を使用した接続を採り上げます。サーバーサイドと言いつつ、オプションを指定するだけとはいえ、cx_Oracle側でもコーディングが必要です。なお、DRCPとクライアントサイドのコネクションプールは併用が可能です。
準備:Oracle Database側
DRCPの操作はDBMS_CONNECTION_POOLというPL/SQLユーティリティ・パッケージを使用します。以下SQL*Plusでの利用例です。マルチテナント構成の場合は、コンテナ・データベースに接続して実施する必要があります。
■DRCPの設定
execute dbms_connection_pool.configure_pool(minsize=>5, maxsize=>5)
■DRCPの起動
execute dbms_connection_pool.start_pool
■DRCPの起動
execute dbms_connection_pool.stop_pool
■DRCPの定義内容の確認
ディクショナリDBA_CPOOL_INFOを検索してください。
■DRCPの稼働状況の確認
動的パフォーマンスビューV$CPOOL_STATSを検索してください。他にもV$CPOOL_CC_STATS、V$CPOOL_CONN_INFOといったビューが存在します。
(参考)Oracle Database の DRCP(データベース常駐接続プーリング)の MINSIZE と MAXSIZE を 1 に設定して、複数セッションから接続してみる。
準備:Oracle Client側
EZCONNECTを利用する場合は事前の準備は不要です。tnsnames.oraを使用する方は、事前に、DRCPを利用する形の設定を指定する必要があります。既存の接続定義への設定追加でも、新規の接続設定追加でも、どちらでも構いません。追加すべき設定は、以下のサンプルの「(SERVER=POOLED)」の部分が該当します。既に「SERVER=DEDICATED」や「SERVER=SHARED」の設定が記述されている場合は置き換える必要があります。
PDB1 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.1.2)(PORT = 1521))
(CONNECT_DATA =
(SERVICE_NAME = pdb1.sub04070214581.vcn0.oraclevcn.com)
(SERVER=POOLED)
)
)
PythonアプリケーションのDRCP接続
まずはサンプルを見てみましょう。
import cx_Oracle
import time
USERID = "test"
PASSWORD = "FooBar"
DESTINATION = "10.0.1.2/pdb1.sub04070214581.vcn0.oraclevcn.com:pooled" # 1.
# DRCPのみ利用
t1 = time.time()
connection = cx_Oracle.connect(USERID, PASSWORD, DESTINATION,
cclass="MYCLASS", purity=cx_Oracle.ATTR_PURITY_SELF) # 2.
t2 = time.time()
connection.close()
print(f"DRCP利用時接続時間 : {t2 - t1}秒")
# DRCPとクライアントサイドのコネクションプールを併用
pool = cx_Oracle.SessionPool(USERID, PASSWORD, DESTINATION, min=2, max=2)
t1 = time.time()
connection = pool.acquire(cclass="MYCLASS", purity=cx_Oracle.ATTR_PURITY_SELF) # 3.
t2 = time.time()
pool.release(connection)
print(f"両コネクションプール併用時接続時間 : {t2 - t1}秒")
本サンプルではまだ解説していないEZCONNECTを使用しています。EZCONNECT利用時にDRCP接続を行うには、コメント1.の部分のように、最後に「:pooled」の設定を追加する必要があります。tnsnames.ora利用時は、SERVER=POOLEDを設定している接続子を指定してください。しかし、cx_Oracleでは、SQL*Plusなどとは異なり、接続設定でDRCPを利用する指定を行っただけでは実際にはDRCPは利用されず、通常接続となります。
cx_OracleでDRCPを利用するためには、コメント2.の部分のように、接続コマンド実施の際にcclass引数とpurity引数の設定が必要となります。
cclass引数は接続クラス名を指定します。接続クラスとは接続に付与する論理名のようなものです。1024バイトまでの文字列が指定可能です。複数の接続で接続クラスを分けると、異なる接続クラスとは該当のコネクションプールが共有されないことが保証されます。一例としては、異なるDBユーザー、異なるアプリケーションなどで異なる接続クラスを指定することで、セッションのより効率的な共有が可能になります。
purity引数はセッションの再利用に関する動きを指定します。以下の値から選択して指定します。
値 | 説明 |
---|---|
cx_Oracle.ATTR_PURITY_NEW | クライアントサイドのコネクションプールを利用していない場合のデフォルト値。接続要求の都度新しい接続を利用する |
cx_Oracle.ATTR_PURITY_SELF | クライアントサイドのコネクションプールを利用している場合のデフォルト値。古い空き接続があれば再利用する |
cx_Oracle.ATTR_PURITY_DEFAULT | 引数無指定時のデフォルト。上記条件により、cx_Oracle.ATTR_PURITY_NEWもしくはcx_Oracle.ATTR_PURITY_SELFのいずれかになる |
最後に、両サイドのコネクションプールを併用する場合、cclass引数とpurity引数は、コメント3.の部分のように、cx_Oracle.SessionPool()ではなく、Connection.acquire()にて指定する必要があります。