Lưu ý rằng bạn đang gọi .getConnection()
nhiều lần. Mặc dù tài liệu có thể rõ ràng hơn về mặt này DataSource.getConnection()
thực sự mở ra một kết nối mới (trái ngược với việc trả về một kết nối hiện có), do đó bạn cần phải đóng từng trường hợp được trả về từ phương thức đó.
Dưới dạng .getConnection()
tạo một phiên bản mới mỗi khi nó được gọi là dòng này là rò rỉ kết nối, vì nó không đóng kết nối được trả về:
pstmt = dataSource.getConnection().prepareStatement(query);
Và dòng này chỉ mở một kết nối mới một cách lãng phí để đóng nó ngay lập tức:
dataSource.getConnection().close();
Có vẻ như bạn đang cố gắng mở và đóng một kết nối riêng biệt cho mỗi lệnh gọi của isValidUser()
(vì bạn đang đóng kết nối khi kết thúc cuộc gọi phương thức đó). Ngay cả khi bạn khắc phục sự cố rò rỉ được mô tả ở trên, đó không phải là cách các kết nối được dự định sử dụng. Thay vào đó, bạn nên chia sẻ một kết nối (hoặc một số lượng nhỏ trong số chúng) trên ứng dụng của mình. Vì vậy, khi chương trình của bạn khởi động, bạn mở một kết nối như vậy và một khi toàn bộ chương trình không cần kết nối nữa (thường ngay trước khi kết thúc) bạn đóng nó.
Loại hành vi này thường được thực hiện bởi chèn phụ thuộc , nơi bạn xây dựng các kết nối và các tài nguyên khác và sau đó chuyển chúng vào bất kỳ đối tượng nào cần chúng - điều này tách biệt quản lý tài nguyên khỏi mã sử dụng các tài nguyên đó. Như một ví dụ đơn giản:
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) {
// ...
}
Theo nguyên tắc chung, các đối tượng chỉ nên chịu trách nhiệm đóng các đối tượng mà chúng xây dựng và nên tránh đóng các đối tượng mà chúng được truyền qua. Trong mã hiện tại của bạn UserDaoImpl
đang mở kết nối, vì vậy nó phải có trách nhiệm đóng nó, nhưng tôi khuyên bạn nên chuyển vào Connection
thay vào đó.