Perhatikan bahwa Anda memanggil .getConnection()
beberapa kali. Meskipun dokumentasi bisa lebih jelas di depan DataSource.getConnection()
sebenarnya terbuka koneksi baru (sebagai lawan mengembalikan yang sudah ada) sehingga Anda harus menutup setiap instance yang dikembalikan dari metode itu.
Sebagai .getConnection()
membuat instance baru setiap kali dipanggil, baris ini merupakan kebocoran koneksi, karena tidak menutup koneksi yang dikembalikan:
pstmt = dataSource.getConnection().prepareStatement(query);
Dan baris ini dengan sia-sia membuka koneksi baru hanya untuk segera menutupnya:
dataSource.getConnection().close();
Sepertinya Anda mencoba membuka dan menutup koneksi terpisah untuk setiap pemanggilan isValidUser()
(karena Anda menutup koneksi di akhir panggilan metode itu). Bahkan jika Anda memperbaiki kebocoran yang dijelaskan di atas, bukan itu yang dimaksudkan untuk digunakan koneksi. Alih-alih, Anda harus berbagi satu koneksi (atau sejumlah kecil koneksi) di seluruh aplikasi Anda. Jadi ketika program Anda dijalankan, Anda membuka koneksi seperti itu, dan sekali seluruh program tidak lagi membutuhkan koneksi (seringkali sesaat sebelum pemutusan) Anda menutupnya.
Perilaku semacam ini biasanya diterapkan oleh injeksi ketergantungan , tempat Anda membangun koneksi dan sumber daya lainnya, lalu meneruskannya ke objek apa pun yang membutuhkannya - ini memisahkan manajemen sumber daya dari kode yang menggunakan sumber daya tersebut. Sebagai contoh sederhana:
public static void main(String[] args) {
DataSource dataSource = createDataSource();
try (Connection connection = dataSource.getConnection()) {
runProgram(connection);
}
}
/**
* this method doesn't need to worry about closing the Connection,
* it trusts that its caller will be responsible for that.
*/
private static void runProgram(Connection connection) {
// ...
}
Sebagai aturan praktis, objek seharusnya hanya bertanggung jawab untuk menutup objek yang mereka buat, dan harus menghindari menutup objek yang mereka lewati. Dalam kode Anda saat ini UserDaoImpl
sedang membuka koneksi, jadi itu harus bertanggung jawab untuk menutupnya, tetapi saya menyarankan untuk meneruskan Connection
sebagai gantinya.