PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Rs232 empfangen -- Datenbank schreiben (mit Java)


aVenger
2005-11-07, 09:05:32
ICh versuche hier krampfhaft ein Programm zu schreiben mit welchem ich einen Wert über die RS232 Schnittstelle empfange und diesen in eine Datenbank speicher mittels Java



package ubertragung;
import at.htlklu.elektronik.schnittstellen.*;
import jdbcsybase.*;
import java.sql.*;


public class Main implements StringListener {
private static JdbcBean db;
private static int maxId;

public static void main(String[] args) throws Exception {

db = new JdbcBean();


db.createConnection("2115090586", "123");

ResultSet rs = db.select("SELECT MAX(smp_nr) AS maxId FROM databasekw");
while (rs.next()) {
maxId=rs.getInt("maxId")+1;
System.out.println("maxId : " + maxId);
}

System.out.println("test");
Main m=new Main();
try{Thread.sleep(2000);}catch(Exception e){}
SerielleSchnittstelle com1=new SerielleSchnittstelle();

com1.setStringDelimiter(com1.DELIMITER_CR);
com1.addStringListener(m);


db.startRWTrans();
/* for(int i=0; i<100;i++){
com1.sendString("B");
try{Thread.sleep(100);}catch(Exception e){}
}*/
db.commitTrans();
//com1.disconnect();
//db.closeConnection();
}


public void stringReceived(StringEvent evt) {

System.out.println("test2");
String sreading=evt.getStringReceived();
int reading=Integer.parseInt(sreading);
System.out.println("W"+sreading);
try{
db.execute("INSERT INTO databasekw VALUES("+maxId+","+reading+",CURRENT TIMESTAMP)");
//db.execute("INSERT INTO databasekw VALUES(0,1337,CURRENT TIMESTAMP)");
maxId++;
}
catch(SQLException e){System.out.println(e.getMessage());}
catch(Exception e){System.out.println(e.getMessage());}


}

}


Dabei kommt jedoch folgende Fehlermeldung
Trying execute() without transaction!

Aber der Wert wird empfangen, da dieser unten ausgegeben wird

HILFE! :redface:

mfg Ave

Monger
2005-11-07, 09:15:56
Dabei kommt jedoch folgende Fehlermeldung
Trying execute() without transaction!

Aber der Wert wird empfangen, da dieser unten ausgegeben wird

HILFE! :redface:

mfg Ave

Ich mag Datenbanken nicht, deshalb alle Angaben ohne Gewähr...


Eine Transaktion stellt einen atomaren Zugriff auf die Datenbank zu. D.h. es kann immer nur eine komplette Transaktion auf einer Datenbank durchgeführt werden. Wird eine Transaktion in der Mitte abgebrochen, wird ein Rollback durchgeführt.
Das macht man, um die Datenintegrität einer Datenbank sicherzustellen. Wenn du z.B. nur Name, aber keine Personalnummer einträgst, kann sich die Datenbank schnell selbst abschießen.

Deshalb musst du Anfang und Ende einer Transaktion markieren. Es gibt irgendeinen Befehl dafür, aber frag mich nicht welchen.

aVenger
2005-11-07, 09:29:46
Ich mag Datenbanken nicht, deshalb alle Angaben ohne Gewähr...


Eine Transaktion stellt einen atomaren Zugriff auf die Datenbank zu. D.h. es kann immer nur eine komplette Transaktion auf einer Datenbank durchgeführt werden. Wird eine Transaktion in der Mitte abgebrochen, wird ein Rollback durchgeführt.
Das macht man, um die Datenintegrität einer Datenbank sicherzustellen. Wenn du z.B. nur Name, aber keine Personalnummer einträgst, kann sich die Datenbank schnell selbst abschießen.

Deshalb musst du Anfang und Ende einer Transaktion markieren. Es gibt irgendeinen Befehl dafür, aber frag mich nicht welchen.

db.startRWTrans();
db.execute(...);
db.commitTrans();

???
is alles drin und sollte passen oder??

Monger
2005-11-07, 10:09:16
db.startRWTrans();
db.execute(...);
db.commitTrans();

???
is alles drin und sollte passen oder??

Ich sag doch: keine Garantie für nix! :)

noid
2005-11-07, 10:28:43
db.startRWTrans();
db.execute(...);
db.commitTrans();

???
is alles drin und sollte passen oder??

äh, mir ist nicht klar wo "stringReceived" aufgerufen wird ?

sollte das nicht zwischen den beiden db-Aufrufen passieren?

Das ist aber nicht der Fall, die stehen doch in der main()?

HellHorse
2005-11-07, 11:11:57
Wenn du z.B. nur Name, aber keine Personalnummer einträgst, kann sich die Datenbank schnell selbst abschießen.
So was sollte nicht möglich sein. Es sollte lediglich eine SQLException zurückkommen.

Deshalb musst du Anfang und Ende einer Transaktion markieren.
Nein, wenn du nichts machst, wird einfach jedes Query als Transaktion angeschaut.

Monger
2005-11-07, 11:55:08
So was sollte nicht möglich sein. Es sollte lediglich eine SQLException zurückkommen.

War ja auch nur ein (schlechtes) Beispiel. Man KANN definitiv durch schlechte Programmierung eine inkonsistente Datenbank erzeugen.


Nein, wenn du nichts machst, wird einfach jedes Query als Transaktion angeschaut.
Ich hatte noch so im Kopf, dass bestimmte Funktionen sich keinen eigenen "Scope" für die Transaktion anlegen. Wenn dies hier schon automatisch geschieht frage ich mich: wie kommt dann die Fehlermeldung zustande?

Shink
2005-11-07, 14:06:03
Also grundsätzlich:
Ich hab zwar - wie vermutlich die meisten hier - natürlich keine Ahnung was in at.htlklu.elektronik.schnittstellen.* und jdbcsybase.* so alles drin ist. Ich nehme mal an, es sollte so ähnlich aussehen:
try{
db.startRWTrans();
db.execute("INSERT INTO databasekw VALUES("+maxId+","+reading+",CURRENT TIMESTAMP)");
db.commitTrans();
maxId++;
}

Wirklich durchdacht wikt das aber alles miteinander nicht.

Shink
2005-11-07, 15:12:09
Eine Transaktion stellt einen atomaren Zugriff auf die Datenbank zu. D.h. es kann immer nur eine komplette Transaktion auf einer Datenbank durchgeführt werden. Wird eine Transaktion in der Mitte abgebrochen, wird ein Rollback durchgeführt.
Das macht man, um die Datenintegrität einer Datenbank sicherzustellen. Wenn du z.B. nur Name, aber keine Personalnummer einträgst, kann sich die Datenbank schnell selbst abschießen.
Deshalb musst du Anfang und Ende einer Transaktion markieren. Es gibt irgendeinen Befehl dafür, aber frag mich nicht welchen.
Der Wahrheitsgehalt dieser Aussage ist nicht allzu hoch zu bewerten, tut mir leid.
Ob eine Transaktion atomar ist, kann man einstellen - meistens ist diese Einstellung aus Performancegründen standardmäßig nicht so gesetzt. Das ist auch nur wichtig, wenn man mehrere Statements auf einmal ausführen will - ein einzelnes INSERT ist immer atomar. Ist sie atomar, so kann sie gar nicht abgebrochen werden. Ein Rollback geschieht z.B. auf Wunsch des Programmierers oder nach einem entdeckten Systemabsturz.
Wenn man nur Name aber keine Personalnummer einträgt kann das je nach Definition der Datenbank gar nicht funktionieren (wenn Personalnummer NOT NULL) - dann geschieht einfach nichts und der JDBC-Treiber bekommt eine SQLException zurück - oder aber auch ein erlaubter Zustand sein.

@noid: stringReceived() wird wahrscheinlich automatisch aufgerufen, sobald Daten vom Rs232 hereinkommen. Dieses Verhalten ist vermutlich/hoffentlich in der übergeordneten Klasse StringListener definiert.

@HellHorse: Theoretisch ja, aber ich weiß nicht, was diese JdbcBean-Klasse so alles macht. (Könnte ja z.B. bei jedem Aufruf eine Exception werfen...)

@Avenger: Dürften wir vielleicht noch den StackTrace sehen?

Kinman
2005-11-07, 23:13:43
Ich hab Dir eh mein Programm gegeben... sieh es Dir halt genau an und frag eventuell nach wenn Du irgendwas nicht verstehst...
Die Verbindung ist halt etwas anders programmiert (soweit ich mich noch erinnern kann).

DBase.java

import java.sql.*;

public class DBase
{
private String name, password, host;
private boolean debug = true;

bean.JdbcBean db = new bean.JdbcBean();

public DBase(String name, String password) throws Exception
{
this.name = name;
this.password = password;
this.host = "127.0.0.1";
}

public int connect() throws Exception
{

try
{
db.createConnection(name, password);
return 0;
}
catch (Exception e)
{
return -1;
}
}


public int execute(String sql_query) throws Exception
{
try
{
db.startRWTrans();
db.execute(sql_query);
db.commitTrans();
return 0;
}
catch (SQLException ex)
{
if (debug == true) System.out.println("\nEXECUTION ERROR!.\nSQL:\n" + sql_query + "\n----------------\n");
db.displaySQLEx(ex);
db.rollbackTrans();
return -1;
}
}


public ResultSet query(String sql_query) throws Exception
{
ResultSet res = null;

try
{
res = db.select(sql_query);
}
catch (Exception e)
{
if (debug == true) System.out.println("\nQUERY ERROR!.\nSQL:\n" + sql_query + "\n----------------\n");
}

return res;
}


public int addMeasurement(String sensorname, int value)
{
ResultSet res = null;
java.util.Date d = new java.util.Date();
long t = d.getTime();
Timestamp ts = new Timestamp(t);
int ID = 1;

//Get new ID
try
{
res = query("SELECT * FROM das_mresults");
if (res != null)
{
while (res.next())
{
ID++;
}
}

if(execute("INSERT INTO das_mresults VALUES (" + ID + ", '" + sensorname + "', '" + value + "', '" + ts + "');") != 0)
{
return -1;
}
}
catch (Exception e)
{
return -1;
}

return 0;
}

public ResultSet getMeasurements()
{
ResultSet res = null;

try
{
res = query("SELECT * FROM das_mresults ORDER BY ID");
}
catch (Exception e)
{
// return -1;
}

return res;
}

public ResultSet getMeasurementsSensor1()
{
ResultSet res = null;

try
{
res = query("SELECT * FROM das_mresults WHERE sensor LIKE '%1' ORDER BY ID");
}
catch (Exception e)
{
// return -1;
}

return res;
}

public ResultSet getMeasurements(int start, int stop)
{
ResultSet res = null;

try
{
res = query("SELECT * FROM das_mresults WHERE ID <= '" + stop + "' AND ID >= '" + start + "'");
}
catch (Exception e)
{
// return -1;
}

return res;
}

}


Und das bean

package bean;

import com.sybase.jdbcx.*;
import java.io.*;
import java.sql.*;
import java.util.*;


public class JdbcBean
{
private static final boolean SHOW_STACK_TRACE = true;
private static final String SQL_LINE = "\r\n---------------------------------";
private SybDriver sybDriver;
private Connection con;
private Statement stmt;
private boolean transactionActive = false;
private String userName = "i473380";
private String passWord = "123";
private boolean debug = false;

public void startRWTrans()
throws SQLException, Exception
{
if (con.isClosed())
throw new Exception("Trying to open a Transaction on a closed Connection");

if (transactionActive)
throw new Exception ("Trying to reopen a open Transaction");

con.setAutoCommit(false);
con.setReadOnly(false);
con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
con.clearWarnings();

transactionActive = true;
if(debug == true)
{
System.out.println(SQL_LINE + SQL_LINE);
System.out.println("ReadWrite-Transaction started!" + SQL_LINE);
}
}

public void commitTrans()
throws SQLException, Exception
{
if (con.isClosed())
throw new Exception("Trying to commit a Transaction on a " +
"closed Connection");

if ( ! transactionActive)
throw new Exception("Trying to commit without Transaction");

con.commit();

con.setAutoCommit(true);
con.setReadOnly(true);
con.clearWarnings();

transactionActive = false;
if(debug == true)
{
System.out.println("COMMIT" + SQL_LINE);
}
}

public void rollbackTrans()
throws SQLException
{
if (con.isClosed())
return;

if ( ! transactionActive)
return;

con.rollback();

con.setAutoCommit(true);
con.setReadOnly(true);
con.clearWarnings();

transactionActive = false;
if(debug == true)
{
System.out.println("ROLLBACK" + SQL_LINE);
}
}

public void createConnection()
throws SQLException, ClassNotFoundException,
InstantiationException,
IllegalAccessException
{
createConnection(userName, passWord);
}

public void createConnection(String userName, String passWord)
throws SQLException, ClassNotFoundException,
InstantiationException,
IllegalAccessException
{
sybDriver = (SybDriver) Class.forName(
"com.sybase.jdbc2.jdbc.SybDriver").newInstance();
sybDriver.setVersion(com.sybase.jdbcx.SybDriver.VERSION_5);
DriverManager.registerDriver(sybDriver);
Properties props = new Properties();
props.put("user", userName);
props.put("password", passWord);
con = DriverManager.getConnection("jdbc:sybase:Tds:db0001a:58102", props);

// Wir verwenden ein globales Statement
stmt = con.createStatement();

// Default wird nur gelesen
con.setAutoCommit(true);
con.setReadOnly(true);
checkForWarning(con.getWarnings());
con.clearWarnings();

transactionActive = false;
}

public ResultSet select(String statement)
throws SQLException
{
ResultSet rs = stmt.executeQuery(statement);
checkForWarning(con.getWarnings());
if(debug == true)
{
System.out.println(statement + SQL_LINE);
}
return rs;
}

public void execute(String statement)
throws SQLException, Exception
{
if ( ! transactionActive)
throw new Exception("Trying execute() without transaction!");

stmt.executeUpdate(statement);
checkForWarning(con.getWarnings());
if(debug == true)
{
System.out.println(statement + SQL_LINE);
}
}

public void closeConnection()
{
try
{
con.close();
}
catch (SQLException ex)
{
}
}

public void checkForWarning (SQLWarning warn)
throws SQLException
{
// If a SQLWarning object was given, display the warning messages.
// Note that there could be multiple warnings chained together

if (warn != null)
{
while (warn != null)
{
if(debug == true)
{
System.out.println(warn.getMessage() + SQL_LINE);
}
warn = warn.getNextWarning();
}
con.clearWarnings();
}
}

public void displaySQLEx(SQLException ex)
throws IOException
{
doDisplaySQLEx(ex,new PrintWriter(System.out, true));
}

public void displaySQLEx(SQLException ex, PrintWriter out)
throws IOException
{
doDisplaySQLEx(ex, new PrintWriter(out));
}

private void doDisplaySQLEx(SQLException ex, PrintWriter out)
throws IOException
{
if(debug == true)
{
out.println("<br>*** SQLException caught ***<br>");
}
while (ex != null)
{
if(debug == true)
{
out.println("SQLState: " + ex.getSQLState() + "<br>");
out.println("Message: " + ex.getMessage() + "<br>");
out.println("Vendor: " + ex.getErrorCode() + "<br><br>");
}
if (SHOW_STACK_TRACE)
{
if(debug == true)
{
out.println("<pre>");
}
ex.printStackTrace(out);
if(debug == true)
{
out.println("</pre>");
}
}
ex = ex.getNextException ();
}
}
}


mfg Kinman

aVenger
2005-11-10, 21:41:10
Ich hab Dir eh mein Programm gegeben... sieh es Dir halt genau an und frag eventuell nach wenn Du irgendwas nicht verstehst...
Die Verbindung ist halt etwas anders programmiert (soweit ich mich noch erinnern kann).

DBase.java

import java.sql.*;

public class DBase
{
private String name, password, host;
private boolean debug = true;

bean.JdbcBean db = new bean.JdbcBean();

public DBase(String name, String password) throws Exception
{
this.name = name;
this.password = password;
this.host = "127.0.0.1";
}

public int connect() throws Exception
{

try
{
db.createConnection(name, password);
return 0;
}
catch (Exception e)
{
return -1;
}
}


public int execute(String sql_query) throws Exception
{
try
{
db.startRWTrans();
db.execute(sql_query);
db.commitTrans();
return 0;
}
catch (SQLException ex)
{
if (debug == true) System.out.println("\nEXECUTION ERROR!.\nSQL:\n" + sql_query + "\n----------------\n");
db.displaySQLEx(ex);
db.rollbackTrans();
return -1;
}
}


public ResultSet query(String sql_query) throws Exception
{
ResultSet res = null;

try
{
res = db.select(sql_query);
}
catch (Exception e)
{
if (debug == true) System.out.println("\nQUERY ERROR!.\nSQL:\n" + sql_query + "\n----------------\n");
}

return res;
}


public int addMeasurement(String sensorname, int value)
{
ResultSet res = null;
java.util.Date d = new java.util.Date();
long t = d.getTime();
Timestamp ts = new Timestamp(t);
int ID = 1;

//Get new ID
try
{
res = query("SELECT * FROM das_mresults");
if (res != null)
{
while (res.next())
{
ID++;
}
}

if(execute("INSERT INTO das_mresults VALUES (" + ID + ", '" + sensorname + "', '" + value + "', '" + ts + "');") != 0)
{
return -1;
}
}
catch (Exception e)
{
return -1;
}

return 0;
}

public ResultSet getMeasurements()
{
ResultSet res = null;

try
{
res = query("SELECT * FROM das_mresults ORDER BY ID");
}
catch (Exception e)
{
// return -1;
}

return res;
}

public ResultSet getMeasurementsSensor1()
{
ResultSet res = null;

try
{
res = query("SELECT * FROM das_mresults WHERE sensor LIKE '%1' ORDER BY ID");
}
catch (Exception e)
{
// return -1;
}

return res;
}

public ResultSet getMeasurements(int start, int stop)
{
ResultSet res = null;

try
{
res = query("SELECT * FROM das_mresults WHERE ID <= '" + stop + "' AND ID >= '" + start + "'");
}
catch (Exception e)
{
// return -1;
}

return res;
}

}


Und das bean

package bean;

import com.sybase.jdbcx.*;
import java.io.*;
import java.sql.*;
import java.util.*;


public class JdbcBean
{
private static final boolean SHOW_STACK_TRACE = true;
private static final String SQL_LINE = "\r\n---------------------------------";
private SybDriver sybDriver;
private Connection con;
private Statement stmt;
private boolean transactionActive = false;
private String userName = "i473380";
private String passWord = "123";
private boolean debug = false;

public void startRWTrans()
throws SQLException, Exception
{
if (con.isClosed())
throw new Exception("Trying to open a Transaction on a closed Connection");

if (transactionActive)
throw new Exception ("Trying to reopen a open Transaction");

con.setAutoCommit(false);
con.setReadOnly(false);
con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
con.clearWarnings();

transactionActive = true;
if(debug == true)
{
System.out.println(SQL_LINE + SQL_LINE);
System.out.println("ReadWrite-Transaction started!" + SQL_LINE);
}
}

public void commitTrans()
throws SQLException, Exception
{
if (con.isClosed())
throw new Exception("Trying to commit a Transaction on a " +
"closed Connection");

if ( ! transactionActive)
throw new Exception("Trying to commit without Transaction");

con.commit();

con.setAutoCommit(true);
con.setReadOnly(true);
con.clearWarnings();

transactionActive = false;
if(debug == true)
{
System.out.println("COMMIT" + SQL_LINE);
}
}

public void rollbackTrans()
throws SQLException
{
if (con.isClosed())
return;

if ( ! transactionActive)
return;

con.rollback();

con.setAutoCommit(true);
con.setReadOnly(true);
con.clearWarnings();

transactionActive = false;
if(debug == true)
{
System.out.println("ROLLBACK" + SQL_LINE);
}
}

public void createConnection()
throws SQLException, ClassNotFoundException,
InstantiationException,
IllegalAccessException
{
createConnection(userName, passWord);
}

public void createConnection(String userName, String passWord)
throws SQLException, ClassNotFoundException,
InstantiationException,
IllegalAccessException
{
sybDriver = (SybDriver) Class.forName(
"com.sybase.jdbc2.jdbc.SybDriver").newInstance();
sybDriver.setVersion(com.sybase.jdbcx.SybDriver.VERSION_5);
DriverManager.registerDriver(sybDriver);
Properties props = new Properties();
props.put("user", userName);
props.put("password", passWord);
con = DriverManager.getConnection("jdbc:sybase:Tds:db0001a:58102", props);

// Wir verwenden ein globales Statement
stmt = con.createStatement();

// Default wird nur gelesen
con.setAutoCommit(true);
con.setReadOnly(true);
checkForWarning(con.getWarnings());
con.clearWarnings();

transactionActive = false;
}

public ResultSet select(String statement)
throws SQLException
{
ResultSet rs = stmt.executeQuery(statement);
checkForWarning(con.getWarnings());
if(debug == true)
{
System.out.println(statement + SQL_LINE);
}
return rs;
}

public void execute(String statement)
throws SQLException, Exception
{
if ( ! transactionActive)
throw new Exception("Trying execute() without transaction!");

stmt.executeUpdate(statement);
checkForWarning(con.getWarnings());
if(debug == true)
{
System.out.println(statement + SQL_LINE);
}
}

public void closeConnection()
{
try
{
con.close();
}
catch (SQLException ex)
{
}
}

public void checkForWarning (SQLWarning warn)
throws SQLException
{
// If a SQLWarning object was given, display the warning messages.
// Note that there could be multiple warnings chained together

if (warn != null)
{
while (warn != null)
{
if(debug == true)
{
System.out.println(warn.getMessage() + SQL_LINE);
}
warn = warn.getNextWarning();
}
con.clearWarnings();
}
}

public void displaySQLEx(SQLException ex)
throws IOException
{
doDisplaySQLEx(ex,new PrintWriter(System.out, true));
}

public void displaySQLEx(SQLException ex, PrintWriter out)
throws IOException
{
doDisplaySQLEx(ex, new PrintWriter(out));
}

private void doDisplaySQLEx(SQLException ex, PrintWriter out)
throws IOException
{
if(debug == true)
{
out.println("<br>*** SQLException caught ***<br>");
}
while (ex != null)
{
if(debug == true)
{
out.println("SQLState: " + ex.getSQLState() + "<br>");
out.println("Message: " + ex.getMessage() + "<br>");
out.println("Vendor: " + ex.getErrorCode() + "<br><br>");
}
if (SHOW_STACK_TRACE)
{
if(debug == true)
{
out.println("<pre>");
}
ex.printStackTrace(out);
if(debug == true)
{
out.println("</pre>");
}
}
ex = ex.getNextException ();
}
}
}


mfg Kinman

hmm ich sollte das ganze auch verstehen bzw erklären können :biggrin: