LoginSignup
3
0

More than 3 years have passed since last update.

[cx_Oracle入門](第14回) コネクションプールを使用した接続(サーバーサイド)

Posted at

連載目次

連載:cx_Oracle入門 目次

検証環境

  • 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」の設定が記述されている場合は置き換える必要があります。

tnsnames.ora
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接続

まずはサンプルを見てみましょう。

sample14a.py
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()にて指定する必要があります。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0