Lihatlah sumber ConnectionPool.java
Anda sepertinya menemukan cuplikan kode ini di borrowConnection()
metode:
//we didn't get a connection, lets see if we timed out
if (con == null) {
if ((System.currentTimeMillis() - now) >= maxWait) {
throw new SQLException("[" + Thread.currentThread().getName()+"] " +
"Timeout: Pool empty. Unable to fetch a connection in " + (maxWait / 1000) +
" seconds, none available["+busy.size()+" in use].");
} else {
//no timeout, lets try again
continue;
}
}
Jadi menurut ini, koneksi Anda Null .
Nilai con
diambil pada baris:
PooledConnection con = idle.poll();
jika Anda melacak kode, Anda akan melihat idle
adalah (tergantung pada konfigurasi Anda, tetapi secara default) FairBlockingQueue
. Anda dapat memeriksa implementasi untuk mendapatkan petunjuk.
Secara umum Anda selalu harus menutup ResultSets, Statements, dan Connections dan koneksi yang digunakan harus dilepaskan kembali dengan benar ke pool. Tidak melakukannya dengan benar dapat mengakibatkan koneksi tidak pernah ditutup => tidak pernah tersedia lagi untuk digunakan kembali (kolam koneksi "bocor" ).
Saya sarankan Anda membuat beberapa pencatatan rinci tentang keadaan kumpulan dan memantaunya untuk mengisolasi masalahnya.
Beberapa panduan dari Apache untuk mencegah kebocoran kumpulan koneksi database:
removeAbandoned="true"
koneksi database yang ditinggalkan dihapus dan didaur ulang
removeAbandonedTimeout="60"
atur jumlah detik koneksi database tidak aktif sebelum dianggap ditinggalkan
logAbandoned="true"
mencatat jejak tumpukan kode yang mengabaikan sumber daya koneksi database. Ingatlah bahwa "logging Connections yang ditinggalkan menambahkan overhead untuk setiap peminjaman Connection karena stack trace harus dibuat."
Saya masih berpikir sedikit meningkatkan maxWait
value (1200, 1500, 1700 - coba saja, tidak akan ada perbedaan dalam waktu respons dari perspektif pengguna) akan menghapus kasus yang jarang terjadi, di mana Anda masih memiliki masalah.