6.3. JDBCデータソース

トランザクションの実行性能を上げるためには、JDBC コネクションのプール管理によって、コストの高い データベースとの物理的な接続および切断処理を、繰り返し行わないようにすることが重要です。

WebOTX では、JDBC のコネクションをプール管理するためのJDBC データソースを提供しています。こ のJDBC データソースは、Web コンテナやEJB コンテナ上のServlet やEJB から利用することができま す。さらに、CORBA のJava アプリケーションからも利用することができます。

JDBC データソースは、JTA 仕様を実現するWebOTX Transaction Service と組み合わせることで2フェ ーズコミットメントにも対応でき、複雑に分散したデータベースにまたがるトランザクションをデータベース の一貫性を保障して簡単に実現することができます。

JDBC コネクション (java.sql.Connection インスタンス) の取得は、データベースとの物理的なコネクシ ョンの接続処理をともないますので、非常に時間を要します。そのため、JDBC コネクションのプール管理を行 うことが一般的です。 また、アプリケーションを記述するうえでは、データベースや接続プロトコルによらず、統 一的なインタフェースが提供されていることが望まれます。 JDBC データソースでは、これらの要求を満たすた めの機能を備えた、JDBC コネクションのファクトリインタフェースを提供します。

6.3.1. コネクションプール機能

JDBC データソースは、JDBC Optional Package で規定されているコネクションプール機能を提供します。

JDBC データソースは、JDBC コネクションを解放することなく、内部のプールに管理して再利用します。このた め、アプリケーションは、接続にかかるコストを気にすることなく、業務処理を行うたびに、毎回、JDBC コネクシ ョンを取得することができます。

JDBC データソースでは、次のとおり、プール管理するコネクションの数を指定することができます。

また、JDBC データソースでは、次のとおり、プール管理されているコネクションの状態監視を行うことができま す。

ほかに、次のとおり、プール管理されているコネクションの解放契機を調整することができます。

このように、きめ細やかなコネクションプールの管理を行うことができます。

これらの設定に応じて、コネクションの接続および切断契機は次のようになります。

6.3.1.1. 接続契機

initialPoolSize に、0より大きい数を指定した場合は、指定した数のコネクションが、アプリケーション プロセス起動時に接続されます。ただし、CORBA や単体のJava アプリケーションの場合には、プロセス起 動時には接続されません。これらの場合、アプリケーションがコネクション取得API をプロセス内で最初に呼 び出した際に、指定した数のコネクション接続が行われます。

initialPoolSize に0を指定した場合は、アプリケーションがコネクション取得API を呼び出した際に、 コネクションプール内に未使用のコネクションがない場合に、コネクション接続が行われます。

また、コネクション接続のためのAPI 呼び出しまたは運用操作を実行することで、maxPoolSize で指定された 数まで接続を行うことができます。

6.3.1.2. 切断契機

コネクションのクローズを行った時、または、トランザクションが完了した時に、次のいずれかの条件を満た した場合に切断されます。

6.3.2. 分散トランザクション連携機能

アプリケーションは、Java Transaction API (JTA)を使用して、2フェーズコミットに参加することができます。 複 数のデータベースにまたがったトランザクションを実行するような場合には、Transaction サービスによって、デ ータの一貫性が保証されます。 特に、EJB のコンテナでトランザクションの管理を行うように設定した場合に は、アプリケーションでは、分散トランザクションに参加するための特別な処理を記述する必要はありません。

また、useMultiUsersPerTransaction プロパティを指定することで、接続先のデータベースが同じでユーザア カウントが異なるJDBC コネクションを同一グローバルトランザクション内で同時利用することができます。

6.3.3. JNDIサーバとの連携機能

JDBC データソースをJNDI サーバに登録するための運用管理機能を提供しています。 JDBC データソースの 運用管理コマンド、または、WebOTX の統合運用管理コマンドや統合運用管理ツールを使用することで、JDBC データソースのプロパティ情報を登録し、JNDI サーバに登録することができます。一度JNDI サーバに登録さ れたJDBC データソースの情報は、JNDI サーバを再起動した場合にも保持されます。この機能を使うことによ って、アプリケーションは、JNDI API やjavax.sql.DataSource インタフェースといったJava 標準のインタ フェースを使用してデータベースにアクセスすることができますので、移植性の高いビジネスロジックを記述す ることができます。

JDBCデータソースの属性やプロパティの変更内容は、JNDIサーバからJDBCデータソースをlookupする時だけでなく、 JDBCデータソースへの設定変更内容の反映を実行することでも実際の動作へ反映することができます。

6.3.4. コネクション制御機能

JDBC データソースでは、defaultAutoCommit プロパティで、コネクションを払いだす際の自動コミットモー ドのデフォルト値を指定することができます。デフォルトでは、コネクションを払い出す際に、必ず自動コミットと なるように調整されます。アプリケーションで必ずコミットを発行する場合に、デフォルト値を非自動コミットに設 定することで、自動コミットモード変更処理のプログラミングを行う必要がなくなります。ただし、JTA のトランザ クションを実行する場合は例外で、必ず、非自動コミットになります。

また、JDBC データソースでは、JDBC 3.0 以降のOracle のJDBC ドライバを利 用する場合に、maxStatements プロパティで、ステートメントのプール数を指定することができます。この指 定を行うことで、性能を改善することができます。

そのほか、JDBC データソースでは、コネクションの接続に失敗した場合のリトライ回数(connectRetryMax プロパティ) やリトライ間隔 (connectRetryInterval プロパティ)、初期接続の接続リトライ有無 (reconnectInitialPool プロパティ) を指定することができます。

6.3.5. コネクションの共有範囲

JDBC データソースでは、コネクションの共有範囲を変更することができます。特別な指定を行わない場合、 jndiName プロパティが同じJDBC データソースインスタンスから払い出されたコネクションは、Java VM (*1) 内で共有されます。このため、同じJava VM 内で動作する複数のアプリケーション間でコネクションを共有 することができ、容易に、コネクションの数を最小限に抑えることができます。これに対して、useStaticPool プロパティにfalse を設定すると、同一のJDBC データソースのインスタンスを使用する範囲内に閉じてコネクシ ョンが共有されます。

*1: 正確には、Java のクラスローダ内での共有となります。同一のJava VM 内であっても、Web コンテナで はコンテキスト毎、EJB コンテナではEJB 毎、アプレットではコードベース毎に、複数のクラスローダが生 成されます。

6.3.6. コネクションプールのクラスタ制御機能

JDBC データソースでは、複数のJDBC データソースの定義を組み合わせることで、稼動待機、または、負荷 分散型でデータベースサーバの呼び出しを行うことができます。

clusterPoolOption プロパティに”roundrobin”を指定した場合は、clusterPoolOption プロパティを指定したJDBC データソースとclusterPoolNames プロパティに列挙したJDBC データソースをラウンドロビンに呼び出します。 clusterPoolNames プロパティに列挙した各JDBCデータソースに重み(clusterPoolWeight)を設定することによって、異なる処理能力のデータベースサーバの負荷を適切に分散できます。重みが高く設定されたJDBCデータソースの使用頻度が高くなり、そのJDBCデータソースのコネクションを優先的に払い出すことができます。これにより、データベースサーバの負荷分散を実現することができます。

また、clusterPoolOption プロパティに”standby”を指定した場合は、最初にclusterPoolOption プロパティを指 定したJDBC データソースを使用し、データベースサーバの障害検出時にclusterPoolNames プロパティに列挙 したJDBC データソースに切り替えます。この機能と、データベースサーバの障害監視や、初期接続の接続リ トライ機能を組み合わせることにより、データベースサーバで障害が発生した際に、復旧時間を短縮すること が可能となります。

コネクションプールの切り替え契機は、アプリケーションがコネクション取得API を呼び出した時です。そのた め、アプリケーションでは、業務処理を行う際に、その都度、JDBC コネクションを取得する必要があります。

また、JDBC データソースは、JDBC データソースの有効化および無効化操作で一時的にJDBC コネクションの払い 出しができないようにすることができます。これにより、運用停止後のデータベースサーバのメンテナンス時 に、データベースサーバの監視等で呼び出しが行なわれないようにすることができます。また、クラスタ制御対 象のJDBC データソースを呼び出し対象から一時的にはずすこともできます。これにより、アプリケーションか らの呼び出しを抑制しながら、JDBC コネクションの接続などの運用操作を実行することができます。また、 データベースの動的スケールアウトやスケールインへの対応では、JDBCデータソースへの設定変更内容の反映でClusterPoolNamesなどの設定を動的に変更することができます。

6.3.7. データベースとJDBCドライバの対応バージョン

JDBC データソースは、次のデータベースとJDBC ドライバをサポートします。

6.3.7.1. データベース

大規模システムや高い性能が要求されるシステムでは、PostgreSQL 以外のデータベースをお 使いになることをお薦めします。

6.3.7.2. JDBC ドライバ

データベースに含まれるJDBC ドライバの他に、次のJDBC ドライバをサポートします。

その他の製品についても、JDBC 2.0 または、JDBC 3.0、JDBC 4.0、JDBC 4.1 の仕様に準拠しているJDBC ドライバであ れば、使用することができます。ただし、十分な評価を行ってください。WebOTX のJava EE の互換性テスト (CTS)では、DataDirect Connect for JDBC バージョン3.6 を使用した実績があります。そのほか、MySQL Connector /J 5.0 の評価実績があります。

どのJDBC ドライバをご利用になる場合でも、アプリケーションでは、その種別を意識した記述を行う必要はあ りません。JDBC データソースの定義情報を変更し、JNDI サーバに登録し直すことで、使用するJDBC ドライバ を切り替えることができます。

6.3.8. MySQLとそのJDBCドライバ

6.3.8.1. MySQL の概要

MySQL はスウェーデンのMySQL AB 社によって開発されている、人気の高いオープンソースのデータベース管理システムです。マルチストレージエンジン・アーキテクチャの採用により、用途や目的に合わせてデータの格納エンジンを変更できることが特徴の一つです。

デュアルライセンス方式を採用しており、利用形態に応じて、商用ライセンスと無償ライセンス(GPL)のいずれかを選択することができます。有償契約により正規のサポートを受けることができ、国内にも複数の代理店を持つなど、ビジネスとしての利用も広がっています。

他のデータベース管理システムと比較して、特に性能を重視した設計となっており、アクセス負荷の高いWeb システムのバックエンドとして採用されるなどの利用実績も豊富です。反面、標準のストレージエンジンではトランザクション機能や外部キーをサポートしないなど、当初、関係データベースとしての機 能に多くの制限がありました。

MySQL 3.23.34 およびMySQL 4.0 以降、トランザクションなどをサポートしたストレージエンジンが使用できるようになり、2005年10月にリリースされたMySQL 5.0 では、ストアドプロシージャやトリガー、ビューに対応するなど、機能面での充実が図られるようになりました。今後、高機能化に伴い、エンタープライズ分野での利用範囲が拡大していくものと思われます。

6.3.8.2. ストレージエンジン

MySQL は、内部データの格納に用いるストレージエンジンとして、次の型を選択することができます。

MyISAM などのトランザクションをサポートしないストレージエンジンでは、自動コミットが行われるため、Java EE トランザクションのトランザクション制御を行うためには利用できません。アプリケーションから直接、java.sql.Connection クラスのcommit やrollback メソッドを呼び出す場合も同様です。

コミットやロールバックといったトランザクションの制御を行うためには、トランザクションをサポートするInnoDBやBDBを利用する必要があります。

6.3.8.3. JDBC ドライバの概要

MySQL のJDBC ドライバはMySQL Connector/J という名称で、開発元のMySQL AB 社より提供されています。MySQL Connector/J は、Pure Java のType4 のドライバであり、MySQL サーバと直接通信を行います。MySQL Connector/J は、JDBC 3.0 に対応しています。

6.3.8.4. JTA の実装の制限

MySQL Connector/J は、バージョン5.0 において、JTA(分散トランザクションのためのAPI)に対応しましたが、次の様な制限があります。

  1. 使用できるストレージエンジンは InnoDB だけです。
  2. 1 トランザクションあたり、1 コネクションしか使用できません。
  3. 同一コネクション内で、グローバルトランザクションとローカルトランザクションの切り替えを行うことができません。
  4. データベースサーバの再起動や通信障害が発生した場合、実行中のトランザクションはすべてロールバックされます。そのため、2 フェーズコミットでトランザクションが準備状態になったとしても、コミットの成功が保証されません。

これらの問題に対する、WebOTXでの対応について、WebOTXでのMySQL対応 で説明します。

6.3.9. WebOTXでのMySQL対応

MySQL に対するWebOTX の対応方針について説明しています。

6.3.9.1. 汎用のデータソースの種別 "JDBC API"

WebOTX のJDBC データソースでは、JDBC ドライバごとにデータソースの種別として文字列を定義することで、簡単にJDBC ドライバやロードするクラスを変更することができます。しかし、現在のところWebOTX のJDBC データソースはMySQL 専用のデータソースの種別を提供していません。そのため、MySQL に接続する場合、データソースの種別には汎用のデータソースの種別 "JDBC API"を指定します。

WebOTXで専用のデータソースの種別を提供する目的の一つに、JDBCドライバのJTAの機能に対応することがあります。しかし、[JTA の実装の制限] で説明したように、MySQLのJDBCドライバにはJTAの実装に制限があるため、現在のところ専用のデータソースの種別を提供していません。

汎用のデータソースの種別 "JDBC API"を利用することにより、[JTA の実装の制限] で説明した制限のうち、(b)と(c)の制限を解除することができます。また、WebOTXの1 フェーズコミット対応リソースとして扱われるため、2フェーズコミットのトランザクションに参加することができます。

6.3.10. MySQLの適用領域

WebOTXで推奨するMySQLと各ストレージエンジンの適用領域について説明します。

6.3.10.1. InnoDB ストレージエンジンの適用領域

ストレージエンジンにInnoDB を使用する場合、汎用のデータソースの種別 "JDBC API"を指定することで、1 フェーズコミット対応リソースの機能により2 フェーズコミットを実現することができます。しかし、この機能にはいくつかの制限があるため、高い信頼性を求められるミッションクリティカルなシステムでの利用には適していないといえます。2 フェーズコミットを行う必要がある場合は、Oracle などの、2フェーズコミットをサポートしていて実際に運用実績のあるRDBMS を利用するべきです。そのため、次のようなシステムで利用することを推奨します。

6.3.10.2. MyISAM ストレージエンジンの適用領域

ストレージエンジンにMyISAM を使用する場合、トランザクション制御を行うことができないという制限があります。そのため、Java EE のトランザクション制御を行う場合には利用できません。その代わり、実行性能ではInnoDB を上回っており、データ更新の取り消しが必要のない次の様な用途で利用することが考えられます。

6.3.10.3. MySQL の適用領域

InnoDB 、MyISAM より、MySQLは比較的単純な、または、高速に処理を行う必要のあるデータを扱う場合に、その利点が生かされるといえます。また、導入コストが低く抑えられるだけでなく、オープンソースソフトウェアでありながらサポートも充実しているなど、業務での利用に適した面があります。反面、分散トランザクション環境下のシステムでの利用に適していないなど、注意が必要な面もあります。更に商用での利用実績において、他のデータベース管理システムに及ばないという課題もあります。