.getConnection()
を呼び出していることに注意してください 複数回。ドキュメントはこの面でより明確になる可能性がありますが、 DataSource.getConnection()
実際に開く (既存の接続を返すのではなく)新しい接続であるため、そのメソッドから返された各インスタンスを閉じる必要があります。
.getConnection()
として 返される接続を閉じていないため、この行が接続リークであると呼ばれるたびに新しいインスタンスを作成します:
pstmt = dataSource.getConnection().prepareStatement(query);
そして、この行は無駄に新しい接続を開き、すぐに閉じます:
dataSource.getConnection().close();
isValidUser()
を呼び出すたびに個別の接続を開いたり閉じたりしようとしているようです (そのメソッド呼び出しの最後に接続を閉じているため)。上記のリークを修正したとしても、それは接続の使用目的ではありません。代わりに、アプリケーション全体で1つの接続(または少数の接続)を共有する必要があります。したがって、プログラムが起動したら、そのような接続を開き、プログラム全体を一度開きます。 接続が不要になり(多くの場合、終了する直前に)、接続を閉じます。
この種の動作は通常、依存性注入 によって実装されます。 、接続やその他のリソースを構築し、それらを必要なオブジェクトに渡す-これにより、リソース管理がそれらのリソースを使用するコードから切り離されます。簡単な例として:
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) {
// ...
}
経験則として、オブジェクトは、作成したオブジェクトを閉じることのみを担当し、渡されたオブジェクトを閉じることは避けてください。現在のコードUserDaoImpl
は接続を開いているので、接続を閉じる責任がありますが、Connection
を渡すことをお勧めします 代わりに。