Nested Transaction, JDBC und Sybase

Status
Nicht offen für weitere Antworten.

fritzr

Mitglied
Hallo,
ich habe ein prinzipielles Problem zu lösen. In unserem Projekt haben wir eine Sybasedatenbank, eine Middleware und ein Java Frontend. Die Middleware bietet verschiedene Methoden an z.B. putObject(), removeObject() etc. an. In diesen Methoden werden die komplexeren Datenbank Zugriffe transaktional angesteuert. Das folgende Listing gibt eine Beispielmethode an...


Code:
public void putUser(User u) throws RepositoryException, SecurityException {
        Connection conn = null;
        RepositoryException exception = null;
        CallableStatement putUserStatement = null;
        CallableStatement changeMappingStatement = null;
        CallableStatement updateUssStatement = null;
        Statement stat = null;
        try {
            conn = getConnection();
            stat = conn.createStatement();
            stat.execute("BEGIN TRANSACTION");
...
...
...
            stat.execute("COMMIT");
        }
        catch (Exception e) {
            exception = new RepositoryException(e);
            try {
                if (stat != null) {
                    stat.execute("ROLLBACK");
                   }
            }
            catch (SQLException sqle) {
                sqle.printStackTrace();
            }
        }
...
    }

Diese Methode fügt einen einen neuen Benutzer hinzu, wenn irgendwas schief läuft, wird die Transaktion zurückgerollt. Nun möchte in einer weiteren Ebene die Möglichkeit haben, mehrere Benutzer zu schreiben, wobei diese gesamte Prozedur am bessten auch in einer eigenen Transaktion laufen sollte. Sobald ein Nutzer nicht angelegt werden konnte, sollen alle anderen ebenfalls zurückgerollt werden.

Also etwas in der Art wie:

Starte Transaktion
putUser(user1);
putUser(user2);
putUser(user3);
Commite Transaktion

Leider finde ich hierzu keinen Weg zur Lösung. Wie kann ich also mehrere Transaktionen in einanderschachteln (Nested Transactions)? Sybase unterstützt dies ja wohl...

Ich möchte jedoch keine neue Middleware-Methode schreiben, die parallel zu der ersten Methode steht.

Grüße
 
M

maki

Gast
Wie kann ich also mehrere Transaktionen in einanderschachteln (Nested Transactions)? Sybase unterstützt dies ja wohl...
Hab schon Persistenz Frameworks erlebt die das nicht können.

Das ist ein Architektur Problem, kein Sybase Problem oder sonstetwas.

Hier wäre spätestens der Zeitpunkt darüber nachzudenken, ob man Transaktionen nicht doch von den einzelnen JDBC aufrufen trennen möchte.
 

fritzr

Mitglied
Also ein wirkliches Framework ( a la Spring) nutzen wir ja in unserem Fall gar nicht. Am liebsten wäre mir zwar der Springansatz, aber so richtig will unsere Middleware da nicht reinpassen. Ich frage mich noch, wie man die Transaktionen davon trennen kann? Die bisherigen Methoden funktionieren ja sehr gut, doch nutzt man mehrere dann fehlt mir hier noch völlig der richtige Ansatz. Wie könnte man vorgehen?

Du sagst die Transaktionen vom JDBC trenne, wo sollte man sie denn dann absetzen?
 
M

maki

Gast
Problem: Ein "use case"/Transaktion ändert mehrere Tabellen/Entitäten, entweder alle oder keine Änderungen sollen übernommen werden.

Dieses Problem ist nicht selten, verbreitete Frameworks versuchen das auf ihre Weise zu meistern.

Selbst wenn du EJBs verwendest, kommst du irgendwann zu diesem Punkt, würdest wahrscheinlich das ApplicationService Pattern einsetzen.

Eine Gemeinsamtkeit ist, dass man den gesamten Vorgang als eine Transaktion sieht, wenn man mehrere "Entitäten" (oder Tabellen) in einem use Case ändert, nicht nur einen Einzelschritt und damit eine einzelne Datenänderung.

Grundprinzip ist das man nicht nach jeder Datenänderung ein "commit" macht, sondern dieses "commit" explizit aus der Aufrufenden Funktionen macht.
 

fritzr

Mitglied
So langsam sehe ich was gemeint sein könnte...

Das Problem ist also, dass ich in der Methode putUser() direkt die Transaktion in der JDBC-Connection starte und beende und andere Methoden von dieser Connection gar nichts wissen...

Sehe ich es richtig, dass man folglich einen Transaktionsmanager wie z.B. Aomikos benutzen könnte, über den die einzelnen Methoden stets ihre Connection beziehen? Das sollte man doch eigentlich recht gut aus dem Code herausziehen können...
 
M

maki

Gast
Ich kenne Aomikos nicht,

aber du hast richtig verstanden.

So etwas selbst zu implementieren kann ein bisschen hakelig sein, musst diesselbe Connection verwenden für alle Änderungen verwenden die als eine Transaktion laufen sollen.

Wenn es nur ein Thread ist der eine Transaktion durchführt, wäre es zB eine Möglichkeit diese in ThreadLocal abzulegen und nach dem Durchlauf von allen Änderungen zu committen, oder eben auch nicht (rollback) ;)

Ein leichtgewichtiges Framework das JDBC kapselt und so etwas unterstützt ist zB iBatis, Spring unterstützt so etwas auch, genauso wie Hibernate und EJBs.
 

fritzr

Mitglied
Ich spiele gerade mit dem Atomikos Framework herum und stelle nun testweise unsere Middleware entsprechend um.
Ich habe den Zugriff auf die Connection vom alten Verfahren umgestellt und verwende nun immer XAConnections.

Nachdem ich die SybaseDB entsprechend umgestellt habe (enable dtm) und sie nun XAConnections zulässt, erhalte ich den folgenden Fehler:

JZ0SF: No Parameters expected. Has query been sent?

Der Ablauf ist folgender:
1) Hole XAConnection
2) Aus der XAConnection erzeuge eine neue Connection
3) Erzeugen eines neuen Aufrufs mit checkEntryStatement = conn.getConnection().prepareCall("{?=call check_path ?,?,?,?,?,?}");
4) checkEntryStatement.execute();
5) wenn ich nun später darauf zurückgreife, kommt der oben beschriebene Fehler. Es scheint als hätte er den Call überhaupt nicht ausgeführt...

Reichen die Informationen aus, um das Problem zu erkennen?

Hier ein Auszug mit merkwürdigen Eigenschaften:

Code:
int tmp = checkEntryStatement.getInt(3);
listStatement = conn.getConnection().prepareCall("{?=call list_directories ?,?}");
tmp = checkEntryStatement.getInt(3);

Währen die erste Zeile ein Resultat liefert, wirft die dritte Zeile den Fehler aus. Es scheint also, als würde ein zweiter Call das erste Statement zu beeinflussen.
 

fritzr

Mitglied
gut ich habe rausgefunden wie man diesen Fehler umgehen kann. Ich muss mir hierzu aus der XAConnection mit getConnection() ein neues Connection Objekt holen und dies dann in meiner Methode konsequent benutzen. Seltsam ist das aber schon.
 

fritzr

Mitglied
maki hat gesagt.:
Wenn es nur ein Thread ist der eine Transaktion durchführt, wäre es zB eine Möglichkeit diese in ThreadLocal abzulegen und nach dem Durchlauf von allen Änderungen zu committen, oder eben auch nicht (rollback) ;)

Hallo Maki, den Tipp würde ich gerne genauer verstehen. Ich denke, dass unsere Anwendung nicht so komplex ist, dass man wirklich mit XAConnections arbeiten muss. Kannst du mir ein kleines Beispiel geben, wie du das mit dem ThreadLocal meinst?

Nochmal zusammengefasst:
Wir haben mehrere Methoden getXYZ die eigentlich nicht in einer Transaktion laufen müssen. Dann gibt es z.B. eine removeObject Methode, die selbst auf mehrere SQL-Statements ausführt und so auf jeden Fall in einer Transaktion laufen sollte.

In unserer Applikation möchte ich nun Methoden ermöglichen, die z.B. 3 Objekte löscht. Dabei sollte die gesamte Arbeit jedoch in einer einzelnen Transaktion laufen, sodass entweder alle oder keines gelöscht werden kann.

Dies führt dazu, dass die removeObject Methode nur einmal aufgerufen wird, dann sollte sie selbst die Transaktion schließen. In anderen Fällen sollte man jedoch die Möglichkeit haben, mehrere Aufrufe zu tätigen, sodass erst am Ende die Transaktion abgeschlossen wird. Die Möglichkeit einer Methodenüberladung besteht natürlich, sodass ich für letztere durchaus Parameter übergeben kann. Ich weiß blos nicht was man da am besten nutzt. Transaktionen? XARessources? Connections?

Da es sich um eine JNDI-Client-Server Architektur handelt, würde ich ungerne, ich glaub es geht nicht mal, die Connectionobjekte nach ausßen reichen.

Danke im Voraus für die Mühe...
 
G

Gast

Gast
Fritzr,

Du kannst die Atomikos SimpleDataSourceBean verwenden:

1-starte JTA Transaktion
2-hole Connection Object
3-schicke deine SQL
4-schliesse Connection
5-wiederholen 2 - 4 falls notwendig
6-commit JTA Transaktion

Dies sollte funktionieren und auch der Aufwand des XAConnection vermeiden.

Guy
 

fritzr

Mitglied
Vielen Dank für die Infos,
nach meinen neusten Tests scheint es so, als würde mir Atomikos in unserem Fall nicht weiterhelfen. Wir haben eine 3-Schichten-Architektur wobei die Middleware in einer, die einzelnen Java-Clients natürlich in einer anderen JVM laufen.

Ich habe zum Testen einen Transaktionsmanager in der Middleware erzeugen lassen und ihn per RMI auch den Clients zur Verfügung gestellt. Es scheint jedoch nicht zu funktionieren, dass die Clients nun Transaktionen starten und commiten können. Ich hörte, hierzu sei die professionelle und kostenpflichtige Variante von Atomikos nötig.

Gibt es alternative Frameworks?
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
OnDemand Lock wait timeout exceeded; try restarting transaction Datenbankprogrammierung 0
ruutaiokwu Begin transaction - rollback, commit...? Datenbankprogrammierung 2
R JPA Transaction Datenbankprogrammierung 2
E Hibernate Session closed nach Transaction commit? Datenbankprogrammierung 7
L Transaction has been rolled back Datenbankprogrammierung 4
Y Hibernate - Transaction Datenbankprogrammierung 22
B SQLite + jdbc + IntelliJ-Consumer = "No suitable driver found..." Datenbankprogrammierung 15
J PC-Start Problem JDBC Connection Datenbankprogrammierung 10
N JDBC SQLITE und Cascading Datenbankprogrammierung 2
D Asynchrone Aufrufe mit jdbc Datenbankprogrammierung 5
Edin JDBC Hilfe Datenbankprogrammierung 2
H JDBC Tabellen ausgeben Datenbankprogrammierung 8
Husamoli345 JSF-JDBC Verbindung Crud Datenbankprogrammierung 15
G MySQL JDBC Metadaten auslesen aus .accdb -> Primärschlüssel manchmal erkannt manchmal nicht Datenbankprogrammierung 3
N Java, sql, jar, JDBC-Treiber in Classpath Datenbankprogrammierung 8
O Create Table per JDBC Fehler: ORA-00922 Datenbankprogrammierung 4
J JDBC anschaulich präsentieren Datenbankprogrammierung 2
Thallius MySQL JDBC auf Linux Server zu mySQL DB auf anderem Linux Server wirft Access denied Datenbankprogrammierung 5
ralfb1105 Oracle JDBC Debugging Datenbankprogrammierung 8
Z [JDBC][MYSQL] Access denied Datenbankprogrammierung 7
Thallius MySQL jdbc schließt Verbindung nach vielen Request von selber Datenbankprogrammierung 8
B MySQL JDBC Kommentarfilter Datenbankprogrammierung 4
Aruetiise MySQL Name JDBC Drive finden Datenbankprogrammierung 4
E Sqlite-jdbc Mitliefern Datenbankprogrammierung 4
R jdbc-Zugriff Nicht erlaubt ? Datenbankprogrammierung 16
S probleme mit dem jdbc treiber Datenbankprogrammierung 1
Thallius MySQL Merkwürdiges JDBC Verhalten bei VPN Verbindung. Datenbankprogrammierung 7
O JDBC Daten in zwei Tabellen mit zwei foreach-Schleifen einfügen (insert into) Datenbankprogrammierung 1
F MySQL JDBC Problem Datenbankprogrammierung 5
C JDBC und SQLite Datenbank Datenbankprogrammierung 8
looparda SQLite Active JDBC Abstraktion Datenbankprogrammierung 2
J JDBC SQL Statement mit Parameter Datenbankprogrammierung 7
S JDBC PreparedStatement durchiterieren Datenbankprogrammierung 6
J RESTServie + JDBC + No suitable driver found for jdbc Datenbankprogrammierung 4
KaffeeFan JDBC/ODBC-Bridge entfernt Datenbankprogrammierung 4
S sun.jdbc.odbc.JdbcOdbcDriver wird nicht gefunden Datenbankprogrammierung 2
J Fehlende DatenbankView nach einbeziehen von JDBC Datenbankprogrammierung 3
A Mit JDBC auf postgreSQL Datenbank zugreifen Datenbankprogrammierung 5
C PostgreSQL JDBC + PostgreSQL: getLong liefert 0 statt NULL Datenbankprogrammierung 2
flenst111 SQL-Statement Wie konfiguriert man JDBC-Connect.richtig, damit es bei riesigen Tabs keinen Speicherüberlauf gibt? Datenbankprogrammierung 1
M JDBC Tabellen mit Boolean Spalten können nicht erstellt werden. DB Updaten - wie? Datenbankprogrammierung 6
S JDBC mit Postgres DB connecten Datenbankprogrammierung 3
A Eine MySQL Zeile mit JDBC löschen Datenbankprogrammierung 5
D JDBC - Verständnisfrage Datenbankprogrammierung 2
C Tabelle erstellen mit Apache JDBC-Util Datenbankprogrammierung 1
L Conversion-Error bei JDBC Date Literals Datenbankprogrammierung 3
X MySQL DB-verbindung ohne JDBC/ODBC Datenbankprogrammierung 1
F sun.jdbc.odbc.jdbcodbcdriver wird nicht gefuden Datenbankprogrammierung 3
J Keine Verbindung zu MSSQL DB mit JDBC Datenbankprogrammierung 3
U JDBC prepaird Statements Datenbankprogrammierung 4
B MySQL JDBC Zugriff auf entfernt Datenbank, fehlende Rechte Datenbankprogrammierung 2
Q MySQL JDBC-Treiber Problem Datenbankprogrammierung 2
R Transaktionen von mehreren Anwendungen aus - JDBC Datenbankprogrammierung 3
N MySQL com.microsoft.sqlserver.jdbc.SQLServerException: Die Verbindung wurde geschlossen. Datenbankprogrammierung 1
N JDBC: rollback() bei Exception geht nicht!? Datenbankprogrammierung 1
C Dateipfad des jdbc Treibers Datenbankprogrammierung 2
G JDBC Connect nur über SID fehlerfrei möglich Datenbankprogrammierung 2
R Oracle jdbc Zugriff auf Oracle Datenbankprogrammierung 2
T JDBC Fehler Datenbankprogrammierung 2
J JDBC via Singleton Datenbankprogrammierung 12
Z PostgreSQL JDBC mit Postgresql Datenbankprogrammierung 2
B No suitable driver found for jdbc:oracle:thin:@$HOST:$PORT:$SID Datenbankprogrammierung 7
K JDBC via Netzwerk Datenbankprogrammierung 4
B JDBC Connection Fehler Datenbankprogrammierung 8
K JDBC- In Java "stored procedure" erstellen für DB2,OracleSql ... Datenbankprogrammierung 3
J JDBC in Library|"Treiber konnte nicht geladen werden"" Datenbankprogrammierung 2
B JDBC-Connection: Data source name too long Datenbankprogrammierung 3
D JDBC insert mit select abfrage Datenbankprogrammierung 5
A JDBC Prepared Statement Autoincrement Datenbankprogrammierung 3
H JDBC prüfen ob Table existiert Datenbankprogrammierung 3
crashfinger jdbc-connection mit jre7 funktioniert nicht Datenbankprogrammierung 5
0 JDBC Oracle Verbindungsaufbau Datenbankprogrammierung 6
Q Oracle Linux: ClassNotFoundException: oracle.jdbc.driver.OracleDriver Datenbankprogrammierung 6
B JDBC MySQL Statement Datenbankprogrammierung 3
F Oracle Oracle JDBC Anbindung unter Glassfish 3.1.2 Datenbankprogrammierung 3
V PostgreSQL JDBC Treiber fehlt Datenbankprogrammierung 6
Y JDBC - Datenbankabfrage Webserver Datenbankprogrammierung 4
C JDBC Datenbank funktioniert nicht Datenbankprogrammierung 7
C JDBC , JDO oder JPA Datenbankprogrammierung 17
J MySQL Datenbank konfigurieren, JDBC, MySQL oder Hibernate Datenbankprogrammierung 2
P JDBC Verbindung zur DB klappt nicht Datenbankprogrammierung 6
J Java - JDBC Verbindung zur Datenbank nicht möglich Datenbankprogrammierung 10
K JDBC Buch kaufen? Datenbankprogrammierung 3
K Hibernate vs. JDBC Datenbankprogrammierung 4
K JDBC Driver not found Datenbankprogrammierung 10
GianaSisters Per JDBC auf Microsoft SQL 2005 Datenbankprogrammierung 24
S ich brauche tipps für JDBC Datenbankprogrammierung 4
Paristick MSSQL - JDBC Exception beim Registrieren Datenbankprogrammierung 5
S Applet stucks at SQL Connection (jTDS JDBC) Datenbankprogrammierung 15
R MySQL Voraussetzungen für eine erfolgreiche Datenbankanbindung mittels JDBC Datenbankprogrammierung 2
c_sidi90 JDBC Oracle Connection schlägt fehl Datenbankprogrammierung 2
J jdbc-dataSource in Klassen nutzen Datenbankprogrammierung 2
H Rechnen in Datenbanken - JDBC Mittel der Wahl? Datenbankprogrammierung 32
K MySQL JDBC - Access Datenbank - unbekannter TabellenName Datenbankprogrammierung 4
D JDBC Fehler beim laden der nativen Bibliothek db2jcct2 Datenbankprogrammierung 9
J MySQL Verbindung über JDBC scheitert immer Datenbankprogrammierung 2
I Master/Detail Tabellen mit JDBC und Swing Datenbankprogrammierung 10
S MSSQL JDBC "Driver class not found" Datenbankprogrammierung 9
E Datenbankverbindung mit Oracle JDBC und Eclipse Plugin Quantum db Datenbankprogrammierung 2
ruutaiokwu jdbc connection als singleton Datenbankprogrammierung 11

Ähnliche Java Themen


Oben