Wie man richtig schließen datasource-Verbindung?
Habe ich diese Klasse aber Im nicht sicher, wie man richtig enge Verbindung, weil ich immer noch diese Fehlermeldung, obwohl ich nur 3 Benutzer angemeldet, aber mit mehreren sql-Abfragen.
> com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: > Data source rejected establishment of connection, message from > server: "Too many connections"
import java.io.File;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.sql.DataSource;
public class UserDaoImpl implements UserDao
{
DataSource dataSource;
public DataSource getDataSource()
{
return this.dataSource;
}
public void setDataSource(DataSource dataSource)
{
this.dataSource = dataSource;
}
public boolean isValidUser(String username, String password) throws SQLException
{
PreparedStatement pstmt = null;
ResultSet resultSet = null;
boolean rt = false;
try{
PasswordEncryptor pws = new PasswordEncryptor();
String encryptedPass = pws.encrypt(password);
String query = "Select count(1) from userdetails where username = ? and password = ?";
pstmt = dataSource.getConnection().prepareStatement(query);
pstmt.setString(1, username);
pstmt.setString(2, encryptedPass);
resultSet = pstmt.executeQuery();
if (resultSet.next()){
rt = (resultSet.getInt(1) > 0);
}
else{
rt = false;
}
}
catch(Exception e){
e.printStackTrace();
}
finally{
resultSet.close();
pstmt.close();
dataSource.getConnection().close();
}
return rt;
}
}
SpringConfiguration.xml
<bean name="userDao" class="com.spring.acadconnect.services.UserDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/acadconnect" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
Du musst angemeldet sein, um einen Kommentar abzugeben.
dataSource.getConnection()
wird immer eine neue Verbindung, daher sind Sie nicht schließen die Verbindung, die Sie denken. Müssen SieDataSourceUtils.getConnection()
um die aktive Verbindung von den aktuellen thread oder sonst speichern die Referenz zurückgegeben, wie conn = dataSource.getConnection() und der Aufrufconn.close()
DataSource
vs.DataSourceUtils
im detail. Beachten Sie, dass wenn SieDataSourceUtils
dannUserDaoImpl
sollte nicht anrufenConnection.close()
(aber ein Teil der Anwendung noch braucht, um zu verwalten, schließen Sie die Anschlüsse).Beachten Sie, dass Sie anrufen
.getConnection()
mehrere Male. Obwohl die Dokumentation könnte klarer sein, an dieser frontDataSource.getConnection()
eigentlich öffnet eine neue Verbindung (als Gegensatz zu der Rückkehr eine vorhandene) so müssen Sie schließen Sie jede Instanz zurückgegeben, die aus dieser Methode.Als
.getConnection()
erstellt eine neue Instanz jedes mal, wenn es heißt, diese Linie ist eine Verbindung undicht, da es nicht dem schließen der Verbindung zurückgegeben:Und diese Linie verschwenderisch öffnet eine neue Verbindung nur sofort zu schließen, es:
Es sieht aus wie Sie versuchen, zu öffnen und zu schließen, eine separate Verbindung mit jedem Aufruf
isValidUser()
(da Sie beim schließen der Verbindung am Ende der Methode call). Selbst wenn Sie fix das Leck oben beschrieben, das ist nicht, wie die verbindungen verwendet werden sollen. Stattdessen sollten Sie teilen eine Verbindung (oder eine kleine Anzahl von Ihnen) über Ihre Bewerbung. Also, wenn Ihr das Programm startet, öffnen Sie eine solche Verbindung, und einmal das ganze Programm nicht mehr benötigt, die Verbindung (oft kurz vor dem beenden) schließen Sie es.Diese Art von Verhalten ist Häufig implementiert,dependency injection, wo Sie bauen Ihre verbindungen und andere Ressourcen, und geben Sie dann in das, was Objekte, die Sie brauchen - das entkoppelt resource management aus dem code, der nutzt diese Ressourcen. Als ein stark Vereinfachtes Beispiel:
Als Faustregel gilt, sollten Objekte nur verantwortlich für das schließen von Objekten, die Sie konstruieren, und Sie sollten vermeiden, schließen, Objekte, die Sie übergeben werden. In Ihrer aktuellen code
UserDaoImpl
ist die Verbindung geöffnet, so sollte es sein, verantwortlich für das schließen, aber ich bin darauf hindeutet vorbei in dieConnection
statt.versuchen, diese stattdessen.
und später, wenn Sie brauchen nicht die Verbindung zur Datenbank nicht mehr nur über
Update: