Hallo zusammen.
Ich habe mir für ein Java Programm einen MySQL Wrapper geschrieben, damit es schlichtweg einfacher für mich ist im Programm Datenbankverbindungen aufzubauen und Querys abzusetzen.
Jetzt ist es so, dass die Daten für die DB aus x Threads kommen können.
Das Programm analysiert kurz gesagt hot plug devices (usb festplatten und sticks) und startet sobald es mitbekommt, dass ein neues Gerät angeschlossen wurde ein Thread das seinerseits Änderungen auf genau diesem gerade angeschlossenen Laufwerk überwacht und die gefunden Daten dann in die
DB Speichert (und das auch fortan tut, bis die Platte getrennt wird).
Und nun zum Problem:
Die Daten in der DB sind zum Teil (nicht komplett!) völlig wirr. Ich war nicht in der Lage herauszufinden, wann genau das passiert, wann also die Daten Integrität über die Wupper geht. Aber ich mutmaße,
dass das passiert, wenn 2 Threads gleichzeitig meinen DB Wrapper (Objekt) benutzen *von dem es nur eine Instanz gibt*
Mit wirren Daten meine ich, dass *Teile* des Inhalts einer Festplatte in der DB der falschen Festplatte (dafür gibts Einträge in der DB) zugeordnet werden.
Aber letztendlich macht das Programm nicht mehr als rekursiv über den Inhalt der Platte zu iterieren und alles in die DB zu speichern. Mehr passiert da nicht. An der Stelle kann also eigentlich kein wirr-warr entstehen.
Kann es also sein, dass die "gleichzeitige" Benutzung des DB Wrappers aus 2 verschiedenen Threads heraus Ressource Probleme verursacht die Daten völlig wirr und über Kreuz in die DB schreiben?
Hier der DB Wrapper:
Danke im Voraus!
Liebe Grüße, Serjoscha
ps. ich nehme auch gerne Tipps für eine Alternative zu meinem eigenen DB Wrapper entgegen
Ich habe mir für ein Java Programm einen MySQL Wrapper geschrieben, damit es schlichtweg einfacher für mich ist im Programm Datenbankverbindungen aufzubauen und Querys abzusetzen.
Jetzt ist es so, dass die Daten für die DB aus x Threads kommen können.
Das Programm analysiert kurz gesagt hot plug devices (usb festplatten und sticks) und startet sobald es mitbekommt, dass ein neues Gerät angeschlossen wurde ein Thread das seinerseits Änderungen auf genau diesem gerade angeschlossenen Laufwerk überwacht und die gefunden Daten dann in die
DB Speichert (und das auch fortan tut, bis die Platte getrennt wird).
Und nun zum Problem:
Die Daten in der DB sind zum Teil (nicht komplett!) völlig wirr. Ich war nicht in der Lage herauszufinden, wann genau das passiert, wann also die Daten Integrität über die Wupper geht. Aber ich mutmaße,
dass das passiert, wenn 2 Threads gleichzeitig meinen DB Wrapper (Objekt) benutzen *von dem es nur eine Instanz gibt*
Mit wirren Daten meine ich, dass *Teile* des Inhalts einer Festplatte in der DB der falschen Festplatte (dafür gibts Einträge in der DB) zugeordnet werden.
Aber letztendlich macht das Programm nicht mehr als rekursiv über den Inhalt der Platte zu iterieren und alles in die DB zu speichern. Mehr passiert da nicht. An der Stelle kann also eigentlich kein wirr-warr entstehen.
Kann es also sein, dass die "gleichzeitige" Benutzung des DB Wrappers aus 2 verschiedenen Threads heraus Ressource Probleme verursacht die Daten völlig wirr und über Kreuz in die DB schreiben?
Hier der DB Wrapper:
Java:
package misc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Logger;
import com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException;
public class MySQL_Wrapper {
private Connection con;
private String user, pass, host, db;
private boolean connected;
public MySQL_Wrapper() {
// Explicit set vars to null
this.user = null;
this.pass = null;
this.host = null;
this.db = null;
this.loadDriver();
}
public MySQL_Wrapper(String user, String pass, String host, String db) {
this.user = user;
this.pass = pass;
this.host = host;
this.db = db;
this.loadDriver();
this.connect();
}
private void loadDriver() {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
Logger.getLogger("global").info("KRITISCHER FEHLER: Konnte MySQL Driver nicht laden!\n" + e.getMessage());
}
}
/**
* tells the wrapper to connect to the DB
* @param user
* @param pass
* @param host
* @param db
* @return a boolean which tells wether the connection was successfull or not
*/
public boolean connect(String user, String pass, String host, String db) {
try {
this.con = DriverManager.getConnection( "jdbc:mysql://" + host + "/" + db, user, pass);
connected = true;
return true;
} catch (SQLException e) {
connected = false;
Logger.getLogger("global").info("KRITISCHER FEHLER: Konnte nicht zur Datenbank verbinden!\n" + e.getMessage());
return false;
//System.exit(0); // new: dont exit for it seems the program looses connection from time to time
}
}
public boolean connect() { // delegates
return this.connect(this.user, this.pass,this.host, this.db);
}
public void setConnectionData(String user, String pass, String host, String db){
this.user = user;
this.pass = pass;
this.host = host;
this.db = db;
}
public void disconnect() {
try {
this.con.close();
} catch (SQLException e) {
Logger.getLogger("global").info("Konnte Verbindung zum MySQL-Server nicht trennen.\n" + e.getMessage());
}
}
/**
* Nicht geeignet um Daten aus der Datenbank zu lesen
* @param qry Die Query
* @return affected rows
*/
public int sendQry(String qry) {
if(this.con == null)
Logger.getLogger("global").info("KRITISCHER FEHLER: Du hast eine Query agesetzt ohne vorher eine Verbindung zur DB aufgebaut zu haben");
/**
* Note: Copying the Entries into the Archive Table causes a "Duplicate Entry"-Exception every time...
*/
try {
Statement stmt = this.con.createStatement();
qry = this.escapeQuery(qry); // escape
int affected = stmt.executeUpdate(qry);
return affected;
}
catch (MySQLIntegrityConstraintViolationException e) {
//System.out.println(e.getMessage());
} catch (SQLException e) {
Logger.getLogger("global").info("KRITISCHER FEHLER: Die Query enthält Fehler!\n" + e.getMessage() + "\n" + e.getSQLState());
}
return 0; // im Fehlerfall
}
/**
* Query, die ein Result set zurückgibt... Die benutzung ist etwas hacky umgesetzt
* @param qry
* @param anyVal völlig egal! Kann alles sein, true oder false oder sonst was... der Wert ist völlig egal und wird nur benutzt um eine andere Methoden Signatur zu erhalten
* @return ResultSet der Daten die gefunden worden
*/
public ResultSet sendQry(String qry, Object anyVal) {
if(this.con == null)
Logger.getLogger("global").info("KRITISCHER FEHLER: Du hast eine Query agesetzt ohne vorher eine Verbindung zur DB aufgebaut zu haben");
try {
Statement stmt = this.con.createStatement();
qry = this.escapeQuery(qry); // escape
return stmt.executeQuery(qry);
}
catch (MySQLIntegrityConstraintViolationException e) {
} catch (SQLException e) {
Logger.getLogger("global").info("KRITISCHER FEHLER: Die Query enthält Fehler!\n" + e.getMessage() + "\n" + e.getSQLState());
}
return null; // !!!
}
private String escapeQuery(String baseString) {
// Currently only escape backspaces -> \ to \\
return baseString.replace("\\", "\\\\");
}
public boolean isConnected() {
return connected;
}
}
Danke im Voraus!
Liebe Grüße, Serjoscha
ps. ich nehme auch gerne Tipps für eine Alternative zu meinem eigenen DB Wrapper entgegen