Lägg märke till att du anropar .getConnection()
flera gånger. Även om dokumentationen kan vara tydligare på denna front DataSource.getConnection()
faktiskt öppnar en ny anslutning (i motsats till att returnera en befintlig) så du måste stänga varje instans som returneras från den metoden.
Som .getConnection()
skapar en ny instans varje gång den kallas denna linje är en anslutningsläcka, eftersom den inte stänger anslutningen som returneras:
pstmt = dataSource.getConnection().prepareStatement(query);
Och den här linjen öppnar slösaktigt en ny anslutning bara för att omedelbart stänga den:
dataSource.getConnection().close();
Det verkar som att du försöker öppna och stänga en separat anslutning för varje anrop av isValidUser()
(eftersom du stänger anslutningen i slutet av det metodanropet). Även om du åtgärdar läckan som beskrivs ovan, är det inte så anslutningar är tänkta att användas. Istället bör du dela en anslutning (eller ett litet antal av dem) över din applikation. Så när ditt program startar öppnar du en sådan anslutning, och en gång hela programmet inte längre behöver anslutningen (ofta strax innan den avslutas) stänger du den.
Denna typ av beteende implementeras vanligtvis av beroendeinjektion , där du konstruerar dina anslutningar och andra resurser och sedan skickar dem till de objekt som behöver dem - detta frikopplar resurshantering från koden som använder dessa resurser. Som ett förenklat exempel:
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) {
// ...
}
Som en tumregel bör objekt endast ansvara för att stänga objekt som de konstruerar, och bör undvika att stänga objekt som de passeras. I din nuvarande kod UserDaoImpl
öppnar anslutningen, så den borde vara ansvarig för att stänga den, men jag föreslår att du skickar in Connection
istället.