Guten Tag,
Ich benutze einen Connectionpool für die MYSQL verbindung meiner Webseite.
Jedoch verliert der Server bei langem nicht benutzen die komplette verbindung zu mysql, und ich muss das Projekt neu deployen, damit sie wieder initalisiert wird.
Hier der Connection pool selbst erstmal:
So dann der Initialisierer
Der erste mysql Aufruf kommt zustande wenn kunden sich in den internen Bereich einloggen möchten, dort wird der benutzername und das passwort mit der mysql datenbank abgeglichen.
Jedoch geht dieser connect schon verloren, und die anderen welche im internen dann darauf folgend ablaufen sind ja von dem ersten abhänig :/
dankeeeeeeeeeee
Ich benutze einen Connectionpool für die MYSQL verbindung meiner Webseite.
Jedoch verliert der Server bei langem nicht benutzen die komplette verbindung zu mysql, und ich muss das Projekt neu deployen, damit sie wieder initalisiert wird.
Hier der Connection pool selbst erstmal:
Java:
package database;
import java.sql.*;
import java.util.*;
/**
* Diese Klasse reserviert, recyclet und regelt die
* Datenbankverbindungen über das Speichern der
* verschiedenen Connects in Vectoren
*/
public class ConnectionPool implements Runnable
{
/** Enthält den Datenbanktreiber */
private String driver;
/** Enthält die Datenbankurl */
private String url;
/** Enthält dem Usernamen für die Datenbank */
private String username;
/** Enthält das Passwort für die Datenbank */
private String password;
/** Enthält die maximale Anzahl der DbConnections */
private int maxConnections;
/** Gibt an ob über einen Thread auf freie Connections gewartet
* werden soll, oder eine SQL Exception geworfen wird, wenn alle
* Connects belegt sind
*/
private boolean waitIfBusy;
/** Enthält die verfügbaren Connections */
private Vector availableConnections;
/** Enthält die Verbindungen, die in Betrieb sind */
private Vector busyConnections;
/**
* Gibt an, ob im Hintergrund Connects gebildet werden sollen
* oder nicht
*/
private boolean connectionPending = false;
public ConnectionPool(String driver, String url,
String username, String password,
int initialConnections,
int maxConnections,
boolean waitIfBusy)
throws SQLException
{
this.driver = driver;
this.url = url;
this.username = username;
this.password = password;
this.maxConnections = maxConnections;
this.waitIfBusy = waitIfBusy;
if (initialConnections > maxConnections)
{
initialConnections = maxConnections;
}
availableConnections = new Vector(initialConnections);
busyConnections = new Vector();
for(int i=0; i<initialConnections; i++)
{
availableConnections.addElement(makeNewConnection());
}
}
/**
* Wenn eine Connection aus der Liste geschlossen ist
* oder ueber einen Timeout beendet, wird die Connection aus
* der Liste der gerade benutzten Connection entfernt und
* evtl. wartende Threads werden benachrichtigt, dass jetzt
* wieder eine Connection frei ist, falls das maximale Limit
* an Connections bereits erreicht wurde
* @return Connection Der eigentliche Connect zur Datenbank
* @throws SQLException
*/
public synchronized Connection getConnection()
throws SQLException
{
if (!availableConnections.isEmpty())
{
Connection existingConnection = (Connection)availableConnections.lastElement();
int lastIndex = availableConnections.size() - 1;
availableConnections.removeElementAt(lastIndex);
if (existingConnection.isClosed())
{
notifyAll(); // Freed up a spot for anybody waiting
return(getConnection());
} else
{
busyConnections.addElement(existingConnection);
return(existingConnection);
}
} else
{
/*Hier gibt es drei moegliche Faelle:
* 1. Die Anzahl maximaler Connections ist erreicht
* und es wird eine neue im Hintergrund eingerichtet,
*
* 2. Die Anzahl maximaler Connections ist erreicht und der waitifBusy
* Flag steht auf false. Die SQL Exception geworfen.
*
* 3. Die Anzahl maximaler Connections ist erreicht, aber der waitifBusy
* flag steht auf true. Dann wird gewartet, bis eine Connection frei
* ist.
*/
if ((totalConnections() < maxConnections) &&
!connectionPending)
{
makeBackgroundConnection();
} else if (!waitIfBusy)
{
throw new SQLException("Connection limit reached");
}
try
{
wait();
}catch(InterruptedException ie) {}
return(getConnection());
}
}
/**
* Ein Connect zur Datenbank kann nur hergestllt werden
* wenn eine Verbindung frei ist. Deshalb wird hier
* ein Thread gestartet, der eine Verbindung im
* Hintergrund herstellt und dann auf eine freie Verbindung
* bzw. eine Nachricht wartet, dass eine Verbindung
* freigegeben wurde.
*/
private void makeBackgroundConnection()
{
connectionPending = true;
try
{
Thread connectThread = new Thread(this);
connectThread.start();
} catch(OutOfMemoryError oome)
{
System.out.println("Fehler in database.ConnectionPool: " + oome.getMessage());
}
}
public void run()
{
try
{
Connection connection = makeNewConnection();
synchronized(this)
{
availableConnections.addElement(connection);
connectionPending = false;
notifyAll();
}
} catch(Exception e)
{
System.out.println("Fehler in database.ConnectionPool run(): " + e.getMessage());
}
}
/**
* Stellt den eigentlichen Connect zur Datenbank her.
* @return Connection Die Datenbankverbindung
* @throws SQLException
*/
private Connection makeNewConnection()
throws SQLException
{
try
{
// DbTreiber laden
Class.forName(driver);
// Netzwerkverbindung zur Datenbank herstellen
Connection connection = DriverManager.getConnection(url, username, password);
return(connection);
}catch(ClassNotFoundException cnfe) {
// Exception werfen, falls der Treiber nicht gefunden werden kann
throw new SQLException("Can't find class for driver: " +
driver);
}
}
/**
* Hier werden Connections frei gegeben und aus dem busyConnections Vector
* rausgenommen, um beim Vector für freie Connects (availableConnections)
* eingefügt zu werden
* @param connection Die augenblickliche Connection
*/
public synchronized void free(Connection connection)
{
busyConnections.removeElement(connection);
availableConnections.addElement(connection);
// Allen Threads Bescheid sagen, dass ein Connect frei geworden ist
notifyAll();
}
/**
* Gibt die Anzahl aller Connections zurück
* @return int Die Anzahl der Connection im Vector
*/
public synchronized int totalConnections()
{
return(availableConnections.size() +
busyConnections.size());
}
/**
* Bietet die Moeglichkeit, alle Connections explizit zu schliessen.
* Dies Funktion ist aber mit Vorsicht zu geniessen, wenn noch
* Connects zur Datenbank bestehen. Auserdem werden die ja
* automatisch geschlossen, wenn der GC laeuft.
* Die Funktion bietet jedoch die Moeglichkeit, einer groesseren
* Kontrolle.
*/
public synchronized void closeAllConnections()
{
closeConnections(availableConnections);
availableConnections = new Vector();
closeConnections(busyConnections);
busyConnections = new Vector();
}
/**
* Wird von closeAllConnections() automatisch aufgerufen
* und ist deshalb privat
* @param connections Die Anzahl der Verbindungen
*/
private void closeConnections(Vector connections)
{
try {
for(int i=0; i<connections.size(); i++) {
Connection connection =
(Connection)connections.elementAt(i);
if (!connection.isClosed())
{
connection.close();
}
}
} catch(SQLException sqle)
{
System.out.println("Fehler in database.ConnectionPool: " + sqle.getMessage());
}
}
/**
* Debug Ausgabe für alle Objektparameter
* @see java.lang.Object#toString()
*/
public synchronized String toString() {
String info =
"ConnectionPool(" + url + "," + username + ")" +
", available=" + availableConnections.size() +
", busy=" + busyConnections.size() +
", max=" + maxConnections;
return(info);
}
}
So dann der Initialisierer
Java:
package login;
import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
import database.*;
public class LoginServ extends HttpServlet
{
/**
*
*/
private static final long serialVersionUID = 1303275261224006323L;
private String dbDriver;
private String dbUrl;
private String dbUser;
private String dbPass;
/**
* Für die Instanziierung von database.ConnectionPool()
*/
public static ConnectionPool CON;
/**
* Der eigentliche Datenbankconnect
*/
private Connection connect;
/**
* Die Servletinitialisierung. Hier werden alle notwendigen Parameter
* für den Datenbankconnect geladen und der ConnectionPool wird instanziiert.
* @see javax.servlet.Servlet#init(ServletConfig)
*/
public void init() throws ServletException
{
// Init Parameter holen
dbDriver = "com.mysql.jdbc.Driver";
dbUrl = "jdbc:mysql://sql-cluster01.it-schuth.net:3306/meineDB";
dbUser = "deruser";
dbPass = "meinpass";
try
{
// ConnectionPool Objekt anlegen
CON = new ConnectionPool(dbDriver,dbUrl,dbUser,dbPass,5,20,true);
// Den eigentlichen Connect herstellen
connect = CON.getConnection();
}
catch (SQLException e)
{
System.err.println("Fehler beim aufbauen des Pools: " + e);
}
}
/**
* Die Post Methode des Servlets. Hier werden Username und Passwort ausgelesen,
* damit eine Datenbankabfrage erfolgen kann.
* Die Überprüfung des Users erfolgt über den Aufruf der statischen Methode
* CheckUser.checkUser(Connection,String,String) und je nachdem, ob diese
* Methode true oder false zurückgibt, wird auf die entsprechende Fehlerseite
* umgeleitet oder auf die Anzeigeseite des DbInhaltes.
* @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest, HttpServletResponse)
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
{
String user = request.getParameter("username");
String pass = request.getParameter("password");
if(!CheckUser.checkUser(connect, user, pass, request))
{
try
{
response.sendRedirect("./error_login");
}
catch (IOException e)
{
System.out.println("IOException in LoginServ.class: " + e.getMessage());
}
}else
{
// Das Session Objekt holen und ein Attribut auf 1
// setzten, um es auf jeder Seite abzufragen
try
{
// die Url auf die umgeleitet werden soll
String uri = request.getContextPath() + "/kundenbereich/index.jsp";
// SICHERHEITSLEG
Integer valid = new Integer(geheimeNummer :) );
// SICHERHEITSLEG
HttpSession session = request.getSession(true);
session.setAttribute("valid", valid);
session.setAttribute("username", user);
// autoLoad Functions
beans.CheckValidUser.getFlag(connect, request, user);
beans.CheckValidUser.setID(connect, request, user);
// Weiterleitung
String encodedUrl = response.encodeRedirectURL(uri);
response.sendRedirect(encodedUrl);
}
catch (IOException e)
{
System.out.println("Fehler beim Aufruf von data.jsp: " + e.getMessage());
}
}
}
}
Der erste mysql Aufruf kommt zustande wenn kunden sich in den internen Bereich einloggen möchten, dort wird der benutzername und das passwort mit der mysql datenbank abgeglichen.
Jedoch geht dieser connect schon verloren, und die anderen welche im internen dann darauf folgend ablaufen sind ja von dem ersten abhänig :/
dankeeeeeeeeeee