-
das sieht mir eher nach einer fehlerhaften Implementierung im Java aus, die bei Verwendung einer extra Connection (aus einem ConnectionPool) für jeden SQL Zugriff nicht passieren kann.
Für alternative Lösungsansätze und Berechtigungsprüfungen bräuchte man schon ein wenig mehr Input.
D*B
 Zitat von axl
Auch wenn ich den Zugriff mittels 'synchronize' in der Java-Methode serialisiere taucht dieses Phänomen immer noch auf.
Für eine Antwort wäre ich sehr dankbar. Auch für einen evtl. anderen Lösungsansatz bzgl. Resultsets u. Berechtigungsprüfung.
-
Das ist wahrscheinlich auch das Problem. Jede Abfrage (auch aus verschiedenen Threads) laufen über ein Connection Objekt.
Bisher funktionierte das auch wunderbar. Zumindest als wir noch direkt auf die Tabellen/Views zugegriffen haben.
Aber seit wir aus 'sicherheitsgründen' nur noch über Stored-Procedures zugreifen gibt's hier Probleme.
Bzgl. einer eigenen Connection pro SQL-Abfrage (ConnectionPool) wäre ich wahrscheinlich auf der sicheren Seite. Für mehr Infos diesbezüglich wäre ich Ihnen sehr dankbar.
-
Hallo,
normalerweise verwendet man bei JDBC (und nicht nur da) für jede Transaktion (-> sind bei Commit > 1 SQL Operation) grundsätzlich eine eigene Connection, das vereinfacht alles drastisch (auch die Threading Probleme sind damit automatisch ausgeschlossen). Damit nicht ständig Connections erzeugt und geschlossen werden, hält man sich diese in einem Connection Pool (davon gibt es mehrere OpenSource Implementierungen SourceForge.net: c3p0:JDBC DataSources/Resource Pools oder DBCP - Downloads ). Auf der AS/400 ist das zwar nicht so essentiell, weil da Server seitig eine Art Pool gehalten wird, aber bei externen Reviews sieht man ohne Pool eher schlecht aus.
Das ganze hat allerdings auch zur Konsequenz, dass in der Regel alle Datenbankzugriffe unter demselben Applikationsuser gemacht werden und die Zugriffskontrolle in die Applikation wandert, also gerade icht in einer stored Procedure abgefackelt werden. BTW: ich halte dieses Design für fragwürdig! User spezifische Sichten lassen sich in der Datenbank über inner join zu Berechtigungstabellen wesentlich eleganter und performanter lösen.
Wenn man spezifische Connections benötigt, dann sollte man trotzdem ConnectionPool dazwischen schalten (dann pro Benutzer ein Pool), der macht einiges mehr, wie Connections auf Gängigkeit prüfen, selbständig von Zeit zu Zeit neue zu nehmen, bis hin zum cachen von prepared Statements.
mfg
Dieter Bender
 Zitat von axl
Das ist wahrscheinlich auch das Problem. Jede Abfrage (auch aus verschiedenen Threads) laufen über ein Connection Objekt.
Bisher funktionierte das auch wunderbar. Zumindest als wir noch direkt auf die Tabellen/Views zugegriffen haben.
Aber seit wir aus 'sicherheitsgründen' nur noch über Stored-Procedures zugreifen gibt's hier Probleme.
Bzgl. einer eigenen Connection pro SQL-Abfrage (ConnectionPool) wäre ich wahrscheinlich auf der sicheren Seite. Für mehr Infos diesbezüglich wäre ich Ihnen sehr dankbar.
-
Vielen Dank nochmals für die vielen Anregungen. Mittlerweile habe ich auf Connectionpools umgestellt. Wobei ich aber noch nicht nach jedem SQL eine 'neue' Connection verwende. Zumindest wird jetzt eine Connection auch nur von einem Thread verwendet.
Das Phänomen mit manchmal unsinnigen zurückgegeben Resultsets habe ich aber nach wie vor.
Unter: IBM - SE25763 - OSP-DB-MSGCPD4373 OR EMPTY RESULT SET
habe ich aber folgendes gefunden, wovon ich ausgehe, dass dies unser Phänomen genau beschreibt. Leider haben wir keine AS400 mit höherem Releasestand um dies auch bestätigen zu können.
-
auch der in deinem link beschriebene Fall ist eine grob fehlerhafte Implementierung in Java und kein Bug in der Datenbank:
private static PreparedStatement ps = null;
dieses Konstrukt ist Java seitig nicht Threadsafe!!!
mit solch einem Konstrukt kann ich soviele Connections verwenden, wie ich will - das preparedStatement wird unterm Hintern weg ausgetauscht, und das nicht nur über Threads, sondern über alle Objekte in der JVM, da schüttelts mich, und wenn ich in den Sandalen Socken anhätte, dann hätten meine sich hochrollenden Fußnägel Löcher hinterlassen.
Dieter Bender
 Zitat von axl
Vielen Dank nochmals für die vielen Anregungen. Mittlerweile habe ich auf Connectionpools umgestellt. Wobei ich aber noch nicht nach jedem SQL eine 'neue' Connection verwende. Zumindest wird jetzt eine Connection auch nur von einem Thread verwendet.
Das Phänomen mit manchmal unsinnigen zurückgegeben Resultsets habe ich aber nach wie vor.
Unter: IBM - SE25763 - OSP-DB-MSGCPD4373 OR EMPTY RESULT SET
habe ich aber folgendes gefunden, wovon ich ausgehe, dass dies unser Phänomen genau beschreibt. Leider haben wir keine AS400 mit höherem Releasestand um dies auch bestätigen zu können.
-
Der Link auf die Fehlerbeschreibung war eigentlich mehr wegen der Ähnlichkeit des Fehlers drin. Die Implementierung bei uns sieht anders aus. Wir verwenden auch keine static PreparedStatement Variablen, wie in dem Link beschrieben.
Mittlerweile kann ich (nach sehr mühsamer Arbeit) den Fehler mit Minimalcode und mit nur einem Thread reproduzieren.
Die Exception ist:
java.sql.SQLException: [SQL0901] SQL-Systemfehler.ErrorCode -901
at com.ibm.as400.access.JDError.throwSQLException(JDE rror.java:650)
at com.ibm.as400.access.JDError.throwSQLException(JDE rror.java:621)
at com.ibm.as400.access.AS400JDBCStatement.commonExec ute(AS400JDBCStatement.java:896)
at com.ibm.as400.access.AS400JDBCPreparedStatement.ex ecuteQuery(AS400JDBCPreparedStatement.java:1108)
at testpackage.TestGleicheAbfrage2.main(TestGleicheAb frage2.java:65)
Message [SQL0901] SQL-Systemfehler.
SQLState 58004
und der Code:
package testpackage;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import com.ibm.as400.access.AS400;
public class TestGleicheAbfrage2 {
private static Connection connection;
public static void main(String args) {
try {
try {
Class.forName("com.ibm.as400.access.AS400JDBCDriver",true, AS400.class.getClassLoader());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
connection = DriverManager.getConnection("jdbc:as400://zedv.erl.firma.com;libraries=VOGTJ, *LIBL", "XXX", "YYY");
CallableStatement cs1 = callsptunnel("JFDKNR = 18");
ResultSet rs1 = cs1.executeQuery();
rs1.next();
// ----
CallableStatement cs2 = callsptunnel("JFDKNR is null");
ResultSet rs2 = cs2.executeQuery();
rs2.next();
rs1.close();
rs2.close();
// ----
CallableStatement cs3 = callsptunnel("JFDKNR is null");
ResultSet rs3 = cs3.executeQuery();
rs3.next();
rs3.close();
// ---
CallableStatement cs4 = callsptunnel("JFDKNR = 18");
ResultSet rs4 = cs4.executeQuery();
rs4.next();
// ----
CallableStatement cs5 = callsptunnel("JFDKNR is null");
ResultSet rs5 = cs5.executeQuery();
rs5.next();
rs4.close();
rs5.close();
// ----
CallableStatement cs6 = callsptunnel("JFDKNR is null");
ResultSet rs6 = cs6.executeQuery();
rs6.next();
rs6.close();
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("ErrorCode \t" + e.getErrorCode());
System.out.println("Message \t" + e.getMessage());
System.out.println("SQLState \t" + e.getSQLState());
try {
connection.close();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
private static CallableStatement callsptunnel(String wherestatement) throws SQLException {
String command = "{call SPTUNNEL" +"(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)}";
CallableStatement callablestatement = connection.prepareCall(command);
callablestatement.registerOutParameter(7, Types.CHAR);
callablestatement.registerOutParameter(8, Types.CHAR);
callablestatement.setString(1, "JFDK");
callablestatement.setString(2, "TEST");
callablestatement.setString(3, "4711");
callablestatement.setDouble(4, new Double(0));
callablestatement.setString(5, "MY");
callablestatement.setString(6, "0");
callablestatement.setString(7, "");
callablestatement.setString(8, "");
callablestatement.setString(9, wherestatement);
callablestatement.setString(10, "");
return callablestatement;
}
}
-
Hallo,
das sieht auf den ersten Blick erstmal unverdächtig aus, ich sehe zwar nicht auf den ersten Blick wo Zeile 65 ist (wo er wohl rausdüst). Aufgefallen ist mir allenfalls, dass die CallableStatements nicht geschlossen werden.
Zusätzliche Info könnte man noch bekommen, wenn man den Database Server Job unter debug nimmt (mit separatem User connecten und nach dem Connect WRKOBJLCK MYUSR *USRPRF Job lokalisieren, STRSRVJOB und STRDBG) da müsste man sogar bis in die stored Procedure reinkommen.
Was sagt denn so euer GRPPTF Stand der Database (und den Treiber könnte man mal tauschen.
Für die wohl fällige Fehlermeldung bei IBM wäre es wohl ganz gut, wenn man den Fehler auch in RPG hinbekommt, dann haben die nur noch eine Ausrede.
mfg
Dieter Bender
-
Also rausfliegen tut er hier:
CallableStatement cs6 = callsptunnel("JFDKNR is null");
ResultSet rs6 = cs6.executeQuery();
rs6.next();
rs6.close();
Die CallableStatements werden nur hier im Demoprogramm nicht geschlossen um den Code kürzer zu halten.
In der StoredProcedure war ich auch schon mit dem Debugger drin, konnte aber keine (zumindest für mich) hilfreichen Infos bekommen. Was den GRPPTF-Stand anbelangt werde ich mal mit unserem Sysadmin reden.
Würde es was bringen den Fehler in RPG hinzubekommen? IBM unterstützt (lt. unserem Sysdamin) solche alten Releasestände eh nicht mehr?
-
... was habt ihr denn für einen Releasestand?
- dann wirds mit dem PTF Stand wohl auch Essig sein
- und die Treiberfrage wird interessant, soweit ich mich erinere, gab es da früher mit CallableStatements Probleme (und es gibt da auch Versionsabhängigkeiten von Treiber und OS)
mfg
Dieter Bender
 Zitat von axl
Also rausfliegen tut er hier:
CallableStatement cs6 = callsptunnel("JFDKNR is null");
ResultSet rs6 = cs6.executeQuery();
rs6.next();
rs6.close();
Die CallableStatements werden nur hier im Demoprogramm nicht geschlossen um den Code kürzer zu halten.
In der StoredProcedure war ich auch schon mit dem Debugger drin, konnte aber keine (zumindest für mich) hilfreichen Infos bekommen. Was den GRPPTF-Stand anbelangt werde ich mal mit unserem Sysadmin reden.
Würde es was bringen den Fehler in RPG hinzubekommen? IBM unterstützt (lt. unserem Sysdamin) solche alten Releasestände eh nicht mehr?
-
Unser Versionsstand ist V5R2.
-
PTFs is wohl nichmehr...
bist du denn sicher, ob das von der Datenbank kommt, oder vom Treiber? Debug müsste dann den SQL0901 im Joblog outen (vielleicht sogar ohne debug), dann wäre Ende der Fahnenstange. Beim Treiber könnte man immerhin mal einen anderen (neueren) probieren.
D*B
 Zitat von axl
Unser Versionsstand ist V5R2.
Similar Threads
-
By PeterKarsten in forum IBM i Hauptforum
Antworten: 9
Letzter Beitrag: 10-11-06, 09:40
-
By florian in forum IBM i Hauptforum
Antworten: 10
Letzter Beitrag: 17-05-06, 16:08
-
By us400 in forum NEWSboard Java
Antworten: 6
Letzter Beitrag: 21-01-06, 09:46
-
By Atomik in forum IBM i Hauptforum
Antworten: 7
Letzter Beitrag: 15-02-05, 13:53
-
By KB in forum IBM i Hauptforum
Antworten: 3
Letzter Beitrag: 18-04-01, 15:30
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- You may not post attachments
- You may not edit your posts
-
Foren-Regeln
|
Erweiterte Foren Suche
Google Foren Suche
Forum & Artikel Update eMail
AS/400 / IBM i
Server Expert Gruppen
Unternehmens IT
|
Kategorien online Artikel
- Big Data, Analytics, BI, MIS
- Cloud, Social Media, Devices
- DMS, Archivierung, Druck
- ERP + Add-ons, Business Software
- Hochverfügbarkeit
- Human Resources, Personal
- IBM Announcements
- IT-Karikaturen
- Leitartikel
- Load`n`go
- Messen, Veranstaltungen
- NEWSolutions Dossiers
- Programmierung
- Security
- Software Development + Change Mgmt.
- Solutions & Provider
- Speicher – Storage
- Strategische Berichte
- Systemmanagement
- Tools, Hot-Tips
Auf dem Laufenden bleiben
|
Bookmarks