Programm baut zu viele MySQL Verbindungen auf

Status
Nicht offen für weitere Antworten.

chris01

Mitglied
Hi,

ich verwende den mysql-connector zum Aufbau einer Verbindung zu meinem MySQL server, nun habe ich leider folgendes Problem, während des eintragens baut das Programm sehr viele Verbindungen auf...dadurch ist 1. die performance sehr schlecht und 2. bricht der Server irgendwann ab, nun meine Frage, wie löse ich dieses Problem, das er nur noch eine Verbindung aufbaut und diese dann für die ganze Zeit nutzt?

Hier mal der Code:

Code:
package de.orangemedia.readclasses;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;

import org.apache.commons.codec.digest.DigestUtils;

import de.orangemedia.readclasses.database.*;

public class ImportTagReadIn {

	public static void readTag(String path) throws IOException,
			ClassNotFoundException, SQLException {
		ArrayList<ImportTagGetSet> tags = new ArrayList<ImportTagGetSet>();
		ImportTag database = new ImportTag();
		String str;
		String script = null;
		boolean isScript = false;
		ImportTagGetSet tag = null;
		File dir = new File("<pfad>");
		File[] fileList = dir.listFiles();
		for (File f : fileList) {
			for (String entry : f.list(new TxtFilenameFilter())) {
				BufferedReader in = new BufferedReader(new FileReader(dir + "/"
						+ f.getName() + "/" + entry));
				tags.clear();

				while ((str = in.readLine()) != null) {
					if (str.startsWith("<!--  begin ad tag: ")) {
						tag = new ImportTagGetSet();

						// sitename
						int beginSitename = str.indexOf("P");
						int endSitename = str.indexOf("/");
						String sitename = str.substring(beginSitename,
								endSitename);
						tag.setSitename(sitename);

						// zone
						int endZone = str.indexOf("(");
						String zone = str.substring(endSitename + 1,
								endZone - 2);
						tag.setZone(zone);

						// sizes
						int endSize = str.indexOf(")");
						String size = str.substring(endZone + 1, endSize);
						tag.setSize(size);
					}

					// script und noscript auslesen
					if (str.startsWith("<script")) {
						isScript = true;
						str = str.substring(0, str.length());
						str = str.substring(0, str.length());
						script = new String(str);
					} else if (str.startsWith("<noscript>")) {
						isScript = false;
						tag.setScript(script);
						script = null;
					}

					if (str.startsWith("<noscript>")) {
						isScript = true;
						str = str.substring(0, str.length());
						str = str.substring(0, str.length());
						script = new String(str);
					} else if (str.startsWith("")) {
						isScript = false;
						tag.setNoscript(script);
						tags.add(tag);
						script = null;
					} else {
						if (isScript) {
							script = script + str;
						}
					}
				}
				in.close();

				// Daten in Datenbank speichern

				for (Iterator<ImportTagGetSet> i = tags.iterator(); i.hasNext();) {

					ImportTagGetSet newTag = i.next();
					String script1 = newTag.getScript().substring(53);
					String hash = DigestUtils.md5Hex(script1);

					int exist = database.getHash(hash);
					if (exist == 0) {
						int webSiteId = database
								.webSiteId(newTag.getSitename());
						int TagId = database.insertTag(newTag.getScript(),
								newTag.getNoscript(), newTag.getZone(),
								webSiteId);
						database.parseSize(TagId, newTag.getSize());

					}
				}
				
			}
		}
		database.closeStore();
	}
}

ImportTag Klasse

Code:
package de.util.readclasses.database;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.apache.commons.codec.digest.DigestUtils;

public class ImportTag {
	private static Connection connect;

	public ImportTag() throws ClassNotFoundException, SQLException {
		/** MySQL Datenbanktreiber laden */
		Class.forName("com.mysql.jdbc.Driver");

		/**
		 * Verbindung zur Datenbank aufbauen und Zugangsdaten übergeben
		 * jdbc:mysql://localhost/NamederDatenbank, Benutzername, Passwort
		 */
		ImportTag.connect = DriverManager.getConnection(
				"jdbc:mysql://localhost/test", "user",
				"passwort");
		
	}

	public void closeStore() throws SQLException {
		connect.close();
	}

	/**
	 * 
	 * @param sitename
	 * @return
	 * @throws SQLException
	 */

	public int webSiteId(String sitename) throws SQLException {
		Statement st = connect.createStatement();
		ResultSet rs = st
				.executeQuery("select ID from website where sitename = '"
						+ sitename + "'");
		int webSiteId = 0;
		while (rs.next()) {
			webSiteId = rs.getInt("ID");
		}
		st.close();
		return webSiteId;
	}

	/**
	 * 
	 * @param script
	 * @param noscript
	 * @param zone
	 * @param webSiteId
	 * @return tag_id
	 * @throws SQLException
	 */

	public int insertTag(String script, String noscript, String zone,
			int webSiteId) throws SQLException {

		String script1 = script.substring(53);
		String scriptHash = DigestUtils.md5Hex(script1);

		PreparedStatement stmt = connect
				.prepareStatement(
						"insert into tag(script,noscript,website_id,zone,hashcode) values(?,?,?,?,?)",
						Statement.RETURN_GENERATED_KEYS);
		stmt.setString(1, script);
		stmt.setString(2, noscript);
		stmt.setInt(3, webSiteId);
		stmt.setString(4, zone);
		stmt.setString(5, scriptHash);
		stmt.execute();
		ResultSet rs = stmt.getGeneratedKeys();
		int tag_id = 0;
		if (rs.next())
			tag_id = rs.getInt(1);
		rs.close();
		stmt.close();
		return tag_id;
	}

	/**
	 * 
	 * @param TagId
	 * @param Sizes
	 * @throws ClassNotFoundException
	 * @throws SQLException
	 */

	public void parseSize(int TagId, String Sizes)
			throws ClassNotFoundException, SQLException {
		ImportTag data = new ImportTag();
		String sizes = Sizes.replaceAll(" ", "");
		String[] size = sizes.split(",");

		for (int i = 0; i < size.length; i++) {
			Statement st = connect.createStatement();
			ResultSet rs = st
					.executeQuery("select ID from tag_size where size = '"
							+ size[i] + "'");
			int sizeId = 0;
			while (rs.next()) {
				sizeId = rs.getInt("ID");
			}
			data.insertSize(TagId, sizeId);
			st.close();
		}
	}

	/**
	 * 
	 * @param TagId
	 * @param SizeId
	 * @throws SQLException
	 */

	public void insertSize(int TagId, int SizeId) throws SQLException {
		Statement st = connect.createStatement();
		st.execute("insert into size_id(tag_id,size_id) VALUES('" + TagId
				+ "','" + SizeId + "')");
		st.close();
	}

	/**
	 * 
	 * @param size
	 * @throws SQLException
	 */

	public void insertSize(String size) throws SQLException {
		Statement st = connect.createStatement();
		st.execute("INSERT into tag_size(size) VALUES('" + size + "')");
		st.close();
	}

	/**
	 * 
	 * @param hash
	 * @return
	 * @throws SQLException
	 */

	public int getHash(String hash) throws SQLException {
		Statement st = connect.createStatement();
		ResultSet rs = st.executeQuery("select ID from tag where hashcode = '"
				+ hash + "'");
		rs.last();
		int result = rs.getRow();
		st.close();
		return result;
	}

	/**
	 * 
	 * @param size
	 * @return
	 * @throws SQLException
	 */

	public int getDuplicateSize(String size) throws SQLException {
		Statement st = connect.createStatement();
		ResultSet rs = st.executeQuery("select ID from tag_size where size = '"
				+ size + "'");
		rs.last();
		int result = rs.getRow();
		st.close();
		return result;

	}
	
}

Danke und Gruß

Chris
 
G

Guest

Gast
Es sollte reichen, wenn du im aktuellen Code die Verbindung wieder schliessen würdest.
Siehe z.B. parseSize(...)
Du erstellst dort immer wieder ImportTag Instanzen, schliesst die Verbindung aber nicht.
Dann innerhalb der Schleife u.U. viele Statements, wo ein PreparedStatement (ausserhalb
der Schleife) die bessere Wahlt wäre. Du Schliesst auch nicht immer die ResultSets, was
dazu führt, dass sie erst mit dem Schliessen des Statements freigegeben werden.
Das alles kostet Zeit und Ressourcen. Sollten an irgendeiner Stelle SQLException kommen,
werden weder die Statements, noch die ResultSets freigegeben. Sehr unsicher das ganze.
Das mit dem Class.forName("com.mysql.jdbc.Driver"); brauchst du auch nur einmalig, nicht
jedes mal, wenn eine ImportTag Instanz erstellt wird.

Um auf deine eigentliche Frage zu kommen. Du könntest eine Singleton-Klasse schreiben,
nennen wir sie mal ServiceLocator, die dir die Connection erstellt. Freigeben/Schliessen musst
du sie aber da, wo sie nicht mehr benötigt werden.
 
G

Guest

Gast
Hi,

erstmal vielen Dank für deine Antwort!...
Leider ist mir noch etwas schleierhaft, wo genau ich das ganze jetzt wieder schließen/freigeben muss...könntest du mir evtl. ein kleines Beispiel machen?

Gruß

Chris
 
G

Guest

Gast
So ungefähr
Code:
Connection connection = null;
PreparedStatement statement = null;
try
{
   connection = DBUtil.getConnection(); // neue Connection erstellen oder immmer wieder die gleiche zurückgeben
   statement = connection.prepareStatement(...)
   ...
}
catch(SQLException e)
{
   // Fehlerbehandlung, Logger
}
finally
{
   // Statement schliessen, wenn nicht null.
   DBUtil.safeClose(statement);
   // Connection schliessen oder nix tun, falls nur eine verwendet wird
   DBUtil.safeClose(connection);
}
 

L-ectron-X

Gesperrter Benutzer
Die Connection sollte unbedingt static sein. Achte darauf, dass dann auch nur noch diese Connection zurückgegeben wird.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Programm auf dem PC bringen Datenbankprogrammierung 5
TH260199 Java-Programm. Probleme bei der Umsetzung von einer Kontaktverwaltung. Datenbankprogrammierung 7
P USER Management in SQL übergreifend auf JAVA Programm Datenbankprogrammierung 1
platofan23 MySQL Java Programm findet Treiber für mySQL auf Debian-Server nicht? Datenbankprogrammierung 11
J Brauche Hilfe bei meinem Programm ! Datenbankprogrammierung 12
W Wie liest dieses Java-Programm der Compiler? Datenbankprogrammierung 3
B Java Programm und Dantebank umlagern Datenbankprogrammierung 25
X SQLite SQLite Programm beendet/führt nicht weiter aus Datenbankprogrammierung 12
G Über Internet Datenbank mit Programm abrufen Datenbankprogrammierung 17
M Verbindung von Java Programm zur Acccess Datenbank (mdb-Datei) Datenbankprogrammierung 0
D Daten von einem Server in eigenem Java-Programm benutzen Datenbankprogrammierung 6
P MySQL Java Programm als Dienst MySQL Dump zurück spielen Datenbankprogrammierung 4
T Derby/JavaDB Zugriff auf DB mit exportiertem Programm Datenbankprogrammierung 12
P MySQL Datenbank aus Programm heraus starten Datenbankprogrammierung 3
S MySQL Einfügen in Tabelle nur von Programm zulassen Datenbankprogrammierung 7
C Programm wird nach DB-Eintrag nicht weitergeführt Datenbankprogrammierung 5
M Ein mit Netbeans entwickeltes Programm dokumentieren Datenbankprogrammierung 5
W SELECT oder Programm-Logik Datenbankprogrammierung 10
J Programm <> Datenbank wie effizient nutzen? Datenbankprogrammierung 3
H MySQL Programm mit Datenbank anbindung Datenbankprogrammierung 26
W Interaktion Java-Programm <-> Datenbank Datenbankprogrammierung 14
C H2 Datenbank mit Programm starten Datenbankprogrammierung 2
E MySQL Daten in die Datenbank eingeben via Java Programm Datenbankprogrammierung 3
O MySQL sql Datei einzelner Tabellen erzeugen (über Java Programm) Datenbankprogrammierung 6
J Mit Java Programm - PostgreSQL backup und restore Datenbankprogrammierung 5
R 1 Programm, 2 Datenbanken Datenbankprogrammierung 15
D Werte mit java programm in eine Datenbank einlesen Datenbankprogrammierung 7
S Access vom Programm aus starten Datenbankprogrammierung 8
A Java JDBC Programm bringt auf Unix Server Fehlermeldung Datenbankprogrammierung 4
G Mit Java-Programm Datenbank löschen/neu anlegen Datenbankprogrammierung 5
S Postgresql DB - Performancetest - Programm, Logfile etc. Datenbankprogrammierung 2
M vorschläge bzgl. java programm mit datenbankanbindung Datenbankprogrammierung 4
C wie soll ich eine bean in mein programm integriegren? Datenbankprogrammierung 2
B Importieren in MySQL mit Java-Programm Datenbankprogrammierung 2
B Exportieren aus MySQL mit Java-Programm Datenbankprogrammierung 11
P Wie übergebe ich einen NULL Wert in meinem Java-Programm? Datenbankprogrammierung 7
A Programm in Autostart startet bevor DB gestartet ist Datenbankprogrammierung 2
L Programm-Architektur bei DB-Zugriff Datenbankprogrammierung 6
G Wie baut man eine Anwendung mit DB Zugriff Datenbankprogrammierung 3
R Wie mit zu viele Daten umgehen? Datenbankprogrammierung 2
K Viele verschiedenen SQL Abfragen Datenbankprogrammierung 2
I MySQL Hibernate zu viele Queries Datenbankprogrammierung 2
M Warum ist es suboptimal viele Indexe auf eine Datenbanktabelle zu setzen? Datenbankprogrammierung 4
J viele @Lob (Strings) mit JPA Datenbankprogrammierung 2
O Viele Verbindungen-Exception bei insert Daten zur MySQL-Datenbank Datenbankprogrammierung 2
J In viele verschiedene Datenbanken einfügen Datenbankprogrammierung 3
ARadauer viele datensätze. Datenbankprogrammierung 3
E zu viele offene Cursor, die II. Datenbankprogrammierung 3
M JDBC: Viele Datensätze in Tabelle einfügen: Wie? Datenbankprogrammierung 7
H Wie viele SQL-Statements gehen in ein Batch Datenbankprogrammierung 2
A Viele Abfragen auf einmal: Performance Datenbankprogrammierung 2
S Viele Klassen sollen eine Connection benutzen Datenbankprogrammierung 3

Ähnliche Java Themen

Neue Themen


Oben