MySQLデータベースでC3P0を使用していくつかの単純な読み取り(SELECT)操作を実行しようとすると、割り込み例外(java.lang.InterruptedException)が発生します。並列スレッドの数を100を超えて増やすと、例外が発生します(5、10、20、60、および100で試しました)。私が実行するステートメントは、次のように単純です。
SELECT `Model.id` FROM `Model` LIMIT 100;
私の接続は、次のプロパティを使用して構成されたComboPooledDataSourceからプールされます(C3P0マニュアルも参照)。
c3p0.jdbcUrl=jdbc:mysql...
c3p0.debugUnreturnedConnectionStackTraces=true
c3p0.maxIdleTime=5
c3p0.maxPoolSize=1000
c3p0.minPoolSize=5
c3p0.initialPoolSize=5
c3p0.acquireIncrement=3
c3p0.acquireRetryAttempts=50
c3p0.numHelperThreads=20
c3p0.checkoutTimeout=0
c3p0.testConnectionOnCheckin=true
c3p0.testConnectionOnCheckout=true
user=***
password=***
テストを実行するマシン上のMySQLサーバーは、1024接続を受け入れるように構成されており、実行する単体テストは正常に実行されます(データは期待どおりにデータベースから取得されます)。ただし、C3P0ログファイルに次の警告があります。
15:36:11,449 WARN BasicResourcePool:1876 - com.mchange.v2.resourcepool.BasicResourcePool@9ba6076 -- Thread unexpectedly interrupted while performing an acquisition attempt.
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1805)
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
その警告の理由を知りたいのですが、次に、ソフトウェアの堅牢性と安定性に与える可能性のある影響について知りたいと思います。使用後、結果セット、SQLステートメント、および接続を閉じることに注意してください。最後に、テストが終了したら、メソッドを呼び出してプールを閉じますComboPooledDataSource#close()
。もっと奇妙なことは(そして同期の問題を明らかにするように思われる)、私が以下を使用してプールに十分な時間を与えるならば...
Thread.sleep(10000); // wait for some time
datasource.close();
ログに警告は表示されません!これはC3P0のスレッドセーフの問題を引き起こすと思いますか、それとも私は間違った方法で何かをしていますか?
アップデート1:
すでに述べたものとは別に、を削除するThread.sleep(10000)
と、次の情報がMySQLログファイルに記録されます。
110221 14:57:13 [Warning] Aborted connection 9762 to db: 'myDatabase' user: 'root'
host: 'localhost' (Got an error reading communication packets)
もう少し光を当てるかもしれません...
アップデート2:
これが私のMySQLサーバー構成です。サーバーで許可される最大接続数は1024に設定されています(前述のとおり)。これは、私がやろうとしていることには十分です。
[mysqld]
max_allowed_packet = 64M
thread_concurrency = 8
thread_cache_size = 8
thread_stack = 192K
query_cache_size = 0
query_cache_type = 0
max_connections = 1024
back_log = 50
innodb_thread_concurrency = 6
innodb_lock_wait_timeout = 120
log_warnings
疑問を曖昧にするために、接続の最大数が次のように適切に設定されていることを確認しました。
show global variables where Variable_name='max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 1024 |
+-----------------+-------+
1 row in set (0.00 sec)