JDBCの接続プールオプション:DBCPとC3P0


312

Java / JDBCで利用できる最適な接続プールライブラリは何ですか?

私は2つの主要な候補者を検討しています(無料/オープンソース):

  • Apache DBCP- http: //commons.apache.org/dbcp/
  • C3P0- http: //sourceforge.net/projects/c3p0

私はブログや他のフォーラムでそれらについて多くを読みましたが、決定に達することができませんでした。

これら2つに関連する代替手段はありますか?

回答:


181

DBCPは古く、製品グレードではありません。しばらく前に、2つの社内分析を実施し、2つの負荷と同時実行性を生成して実際の条件下での適合性を評価するテストフィクスチャを作成しました。

DBCPは常にテストアプリケーションに例外を生成し、C3P0が例外なしで処理できる以上のパフォーマンスレベルに到達するのに苦労しました。

C3P0は、DBの切断と再開時の透過的な再接続も堅牢に処理しましたが、DBCPは、リンクがその下から削除された場合、接続を回復しませんでした。さらに悪いことに、DBCPは、基になるトランスポートが壊れていたアプリケーションにConnectionオブジェクトを返していました。

それ以来、4つの主要な高負荷コンシューマーWebアプリでC3P0を使用しており、振り返ることはありません。

更新:何年にもわたって棚に座った後、Apache Commonsの人々はDBCPを休眠状態から脱し、現在もまた活発に開発されているプロジェクトであることがわかりました。したがって、私の元の投稿は古くなっている可能性があります。

そうは言っても、この新しいアップグレードされたライブラリのパフォーマンスはまだ体験していませんし、最近のアプリフレームワークでデファクトであるとも聞いていません。


2
ありがとう!提案されたProxool代替案はどうですか?Hibernateの現在のバージョンには、c3p0とProxoolの両方が付属しています。
Dema

私たちはProxoolを試していませんが、今すぐチェックしてみます:)
j pimmel

5
c3p0にはいくつかの欠点があります。接続のピークを処理できない場合があります。
2010年

3
この回答を最初に投稿してから4年間で状況は大きく変化しましたが、可能であれば、現在のシナリオを共有する更新を追加できますか?
Rajat Gupta 2013

13
HikariCPを強くお勧めしますが、それを書く手伝いをしました。
brettw 2013年

177

BoneCPを試してみることをお勧めます -これは無料でオープンソースであり、利用可能な代替手段よりも高速です(ベンチマークのセクションを参照)。

免責事項:私は著者なので、偏見があると言えます:-)

更新:2010年3月の時点で、新しく書き直されたApache DBCP( "tomcat jdbc")プールよりも約35%高速です。ベンチマークセクションの動的ベンチマークリンクを参照してください。

アップデート#2:(12月'13)4年間でトップになった今、はるかに速い競合他社があります:https : //github.com/brettwooldridge/HikariCP

アップデート#3:(Sep '14)この時点でBoneCPが廃止されることを検討してください。HikariCPに切り替えることをお勧めします

アップデート#4:(15年4月)-ドメインjolbox.comを所有しなくなった


1
BoneCPをTomcatデータソースとして使用してトラブルシューティングを行いたいと思います。私がこれで抱えていた主な問題は、tomcatのlib dirにBoneCPクラス、およびlog4jとgoogleクラスが必要だったということです。これを行うと、接続プールの作品を作った- (WARでいる間、それは働いていなかった) -しかし、それはのTomcatのlog4jの設定と競合し、dealbreakerたアプリケーションから、まったくのログ出力を防止...
jはpimmel

1
これは何よりもlog4jの問題のように聞こえます。forum.jolbox.comに連絡してください。できるだけ早く追跡します。
wwadge

3
1up、BoneCPは素晴らしい。C3P0から切り替えられました。それは私がlog4jdbc-remixへの私の依存関係を取り除くことさえ可能にしました、なぜならそれはボックスからのステートメントのログ記録を可能にするからです!
11

68
あなたが書いていない何かを更新するための+1がより速くなりました!
CorayThan 2014

1
@AndrewScottEvansおそらくv0.7.1に戻すのが最善
wwadge

16

接続がタイムアウトしたときにDBCPで問題が発生したため、c3p0を試しました。これを製品版にリリースする予定でしたが、その後パフォーマンステストを開始しました。c3p0のパフォーマンスが非常に悪いことがわかりました。うまく機能するように設定することができませんでした。DBCPの2倍遅いことがわかりました。

次に、Tomcat接続プールを試しました。

これはc3p0の2倍の速さで、DBCPで発生していた他の問題が修正されました。3つのプールの調査とテストに多くの時間を費やしました。Tomcatにデプロイする場合の私のアドバイスは、新しいTomcat JDBCプールを使用することです。


14

DBCPでの自動再接続の問題について、次の2つの構成パラメーターを使用してみましたか?

validationQuery="Some Query"

testOnBorrow=true

ドキュメントtestOnBorrowデフォルト値を持っているtrueので、もし、validationQuery定義され、それがアプリケーションに渡される前に、DBCPは、すべての接続をテストします。
dma_k '17年


12

数年前からDBCPを使用しています。安定しており、DBサーバーの再起動後も存続します。正しく設定するだけです。少数のパラメータを指定する必要があるだけなので、面倒ではありません。これを機能させるために明示的に設定したパラメーターをリストするシステム生産コードのスニペットを次に示します。

DriverAdapterCPDS driverAdapterCPDS = new DriverAdapterCPDS();
driverAdapterCPDS.setUrl(dataSourceProperties.getProperty("url"));
driverAdapterCPDS.setUser(dataSourceProperties.getProperty("username"));
driverAdapterCPDS.setPassword(dataSourceProperties.getProperty("password"));
driverAdapterCPDS.setDriver(dataSourceProperties.getProperty("driverClass"));

driverAdapterCPDS.setMaxActive(Integer.valueOf(dataSourceProperties.getProperty("maxActive")));
driverAdapterCPDS.setMaxIdle(Integer.valueOf(dataSourceProperties.getProperty("maxIdle")));
driverAdapterCPDS.setPoolPreparedStatements(Boolean.valueOf(dataSourceProperties.getProperty("poolPreparedStatements")));

SharedPoolDataSource poolDataSource = new SharedPoolDataSource();
poolDataSource.setConnectionPoolDataSource(driverAdapterCPDS);
poolDataSource.setMaxWait(Integer.valueOf(dataSourceProperties.getProperty("maxWait")));
poolDataSource.setDefaultTransactionIsolation(Integer.valueOf(dataSourceProperties.getProperty("defaultTransactionIsolation")));
poolDataSource.setDefaultReadOnly(Boolean.valueOf(dataSourceProperties.getProperty("defaultReadOnly")));
poolDataSource.setTestOnBorrow(Boolean.valueOf(dataSourceProperties.getProperty("testOnBorrow")));
poolDataSource.setValidationQuery("SELECT 0");

8

DBCPのパフォーマンスがC3P0やProxoolよりも大幅に高いことを示す記事がいくつかあります。また、私自身の経験では、c3p0には準備済みステートメントプーリングのようないくつかの優れた機能があり、DBCPよりも構成可能ですが、DBCPは使用したどの環境でも明らかに高速です。

dbcpとc3p0の違いは?何もない!(堺開発者ブログ) http://blogs.nyu.edu/blogs/nrm216/sakaidelic/2007/12/difference_between_dbcp_and_c3.html

ブログ投稿のコメントにあるJavaTechの記事「Connection Pool Showdown」なども参照してください。


4
シングルスレッド環境では高速で、バグが多く不安定で、他の場所では単純に壊れます。

7

この記事では、もう1つの代替手段であるProxoolについて説明しています

Hibernateがデフォルトの接続プール実装にc3p0をバンドルする理由を見つけられるかもしれませんか?


7

残念ながらそれらはすべて時代遅れです。DBCPは最近更新されました。他の2つは2〜3年前のもので、多くの未解決のバグがあります。


それは本当です-C3POの最後のリリース(0.9プレリリース)は2007年5月からです。Proxoolの最新リリース(0.9プレリリース)は2008年8月からです。DBCPの最後のリリースも2007年4月からですが、少なくともその安定した1.2リリース。実際にメンテナンスされているものはありますか?
GUSS

4
公平を期すために、これらは大きなプロジェクトではないので、C3P0 / DBCPでの更新が少なくなり、時間が経つと予想されるはずです。
wwadge 2009

7

適切に構成されていれば、dbcpは本番環境で使用できます。

たとえば、1日あたり350000人のビジターの商取引Webサイトで使用され、200接続のプールがあります。

正しく設定されていれば、タイムアウトを適切に処理します。

バージョン2は進行中であり、多くのプロダクションの問題に取り組んできたため、信頼性を高める背景があります。

私たちはそれをバッチサーバーソリューションに使用しており、データベースの何百万もの行で機能する何百ものバッチを実行しています。

tomcat jdbcプールによって実行されたパフォーマンステストは、cp30よりもパフォーマンスが優れていることを示しています。


UBIK LOAD PACK-私たちはDBCP 1.4を使用しており、1万レコードの単一のバッチで常にハングアップしています。Spring Batch + JSR 352を使用しており、HikariCPへの切り替えを考えています。何百ものバッチがスムーズに実行されていると言うとき、DBCP 2.xまたは他のバージョンで実行されていることを意味しますか?また、構成を共有してもらえますか?私たちの設定はmaxActive = 150、minIdle = 15、maxIdle = 75、initialSize = 15ですが、ハングアップが解消されることはありません。validationQueryまたはtestOnBorrow / testOnReturnは使用していません。それを使用することをお勧めしますか?
ヨジェンドラ2016年

4

DBCPで1日半無駄に終わったところです。最新のDBCPリリースを使用していますが、j pimmelとまったく同じ問題が発生しました。私はDBCPをまったくお勧めしません。特に、DBがなくなったときにプールから接続をスローするコツ、DBが戻ったときに再接続できないこと、および接続オブジェクトをプールに動的に追加できないこと(永続的にハングする) JDBCconnect後のI / Oソケット読み取り)

今はC3P0に切り替えています。私は以前のプロジェクトでそれを使用したことがあり、それは魅力のように機能し、実行されました。


4

マルチスレッドプロジェクトを使用している場合は、c3p0が適しています。私たちのプロジェクトでは、DBCPを使用して複数のスレッド実行を同時に使用したため、さらにスレッド実行を使用すると接続タイムアウトが発生しました。したがって、c3p0構成を使用しました。


3

使いやすい優れた代替手段はDBPoolです。

「Javaベースのデータベース接続プールユーティリティ。時間ベースの有効期限、ステートメントキャッシング、接続検証、およびプールマネージャーを使用した簡単な構成をサポートしています。」

http://www.snaq.net/java/DBPool/


DBPoolとBoneCPのベンチマークを行いました。DBPOOLはとりわけ同期のgetConnection()を行い、遠くに遅いBoneCP(参照:よりjolbox.com/forum/viewtopic.php?f=3&t=175を)。
wwadge 2010

3

接続プールを導入する必要があり、目の前には4つのオプションがありました。

  • DBCP2
  • C3P0
  • Tomcat JDBC
  • ひかりCP

基準に基づいていくつかのテストと比較を行い、HikariCPに行くことにしました。HikariCPを選択した理由を説明するこの記事をお読みください。


1

C3P0を最良の方法で実装するには、この回答を確認してください

C3P0

エンタープライズアプリケーションの場合、C3P0が最適なアプローチです。C3P0は、jdbc3仕様とjdbc2 std拡張で説明されているように、接続とステートメントプーリングを実装するDataSourcesを含む、JNDIバインド可能なDataSourcesで従来の(DriverManagerベースの)JDBCドライバーを拡張するための使いやすいライブラリです。C3P0は、DBの切断と再開時の透過的な再接続も堅牢に処理しましたが、DBCPは、リンクがその下から削除された場合、接続を回復しませんでした。

したがって、c3p0およびその他の接続プールでもステートメントキャッシュが準備されているのはこのためです。これにより、アプリケーションコードでこれらすべての処理を回避できます。ステートメントは通常、限られたLRUプールに保持されるため、一般的なステートメントはPreparedStatementインスタンスを再利用します。

さらに悪いことに、DBCPは、基になるトランスポートが壊れていたアプリケーションにConnectionオブジェクトを返していました。c3p0の一般的な使用例は、Apache Tomcatに含まれている標準のDBCP接続プールを置き換えることです。多くの場合、プログラマーは、DBCP接続プールで接続が正しくリサイクルされない状況に遭遇します。この場合、c3p0は価値ある代替品です。

現在のアップデートでは、C3P0には素晴らしい機能がいくつかあります。それらは以下のとおりです。

ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setMinPoolSize();
dataSource.setMaxPoolSize();
dataSource.setMaxIdleTime();
dataSource.setMaxStatements();
dataSource.setMaxStatementsPerConnection();
dataSource.setMaxIdleTimeExcessConnections();

ここで、maxおよびminのpoolsizeは接続の境界を定義します。これは、このアプリケーションが取る最小および最大の接続を意味します。MaxIdleTime()アイドル接続を解放するタイミングを定義します。

DBCP

このアプローチも優れていますが、接続タイムアウトや接続の実現などのいくつかの欠点があります。マルチスレッドプロジェクトを使用している場合は、C3P0が適しています。私たちのプロジェクトでは、DBCPを使用して複数のスレッド実行を同時に使用したため、さらにスレッド実行を使用すると接続タイムアウトが発生しました。したがって、c3p0構成を使用しました。私はDBCPをまったくお勧めしません。特に、DBがなくなったときに接続をプールからスローするコツ、DBが戻ってきたときに再接続できず、接続オブジェクトをプールに動的に追加できない(永続的にハングする) JDBCconnect後のI / Oソケット読み取り)

ありがとう:)


1

私の推薦は

ひかり>ドルイド> UCP> c3p0> DBCP

それは私がテストしたものに基づいています-20190202、私のローカルテスト環境(docker / pool minSize = 1、maxSize = 8の4GB mac / mysql)で、hikariは接続を取得するために1024スレッド×1024回、各スレッドの平均時間を提供できます完了までの時間は100万または200万秒ですが、c3p0は256スレッドx 1024回しか処理できず、各スレッドの平均時間はすでに2100万秒です。(512スレッドが失敗しました)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.