Ergebnis 1 bis 5 von 5

Thema: Persistierung Userfreundlich machen

  1. #1
    Registrierter Benutzer
    Registriert seit
    15.10.2015
    Beiträge
    12
    Hat mir geholfen
    3
    Positive Bewertung 1 in 1 Post

    Persistierung Userfreundlich machen

    Hallo zusammen,

    ich habe folgendes Szenario: Eine einfache Oberfläche mit einer XDevTable und einem entsprechend automatisch erzeugten Formular zum Ändern/Speichern der Datensätze. Die Datensätze die in der Table angeklickt sind, werden selbstverständlich zum Bearbeiten auch im Formular angezeigt. Zusätzlich noch einen Button zum Abbrechen der Aktion. Genau um diesen Button geht es: Ich möchte alle Änderungen die zwischen öffnen und schließen dieses Fensters entstanden sind löschen, wenn gewünscht. Ich dachte, nichts einfacher als das: Beim Button „Speichern“ ist lediglich ein formular.save(false) (also kein sofortiger synchronize mit der Datenbank) zu setzen. Sobald der User nun das Fenster schließt, lasse ich entsprechend synchronizeChangedRows() auf die Virtuelle Tabelle ausführen und alles wird gespeichert, bricht der User ab, mache ich dies natürlich nicht.

    Das Problem ist jedoch, das beim Bearbeiten der Daten die Änderungen zwar vorerst in die VT übernommen werden, klickt man jedoch ein paar Mal vor dem Speichern in der Tabelle rum (einfach auf andere Datensätze) und dann wieder auf den gerade geänderten Datensatz, sind die entsprechenden Änderungen wieder weg. Das erkläre ich mir dadurch, dass Xdev beim Zeilenwechsel die alten Daten wieder neu aus der Datenbank ausließt, da die Änderungen ja noch nicht persistiert wurden. Das ist für den User irritierend und es entsteht der Eindruck, dass die geänderten Zeilen verloren gegangen wären. Wie könnte ich dieses Problem lösen?

    Eine Möglichkeit wäre vielleicht, beim Öffnen des Fensters einfach alle Rows in ein Array zu speichern. Wenn der User Änderungen vorgenommen hat, dann aber doch Abbrechen will, so könnte ich deleteAll auf die VT anwenden und danach das komplette RowArray wieder zurückschreiben… Aber diese Lösung gefällt mir nicht, da ich es unsinnig finde, dass ich das, was ich eigentlich wiederherstellen möchte erst einmal lösche…

    Vielen Dank im Voraus für Eure Antworten!

    Schöne Grüße

    Thomas Körner

  2. #2
    Open.XDEV Team Avatar von Peter Schneider
    Registriert seit
    21.11.2012
    Beiträge
    227
    Blog-Einträge
    1
    Hat mir geholfen
    4
    Positive Bewertungen 13 in 12 Posts
    Hallo Thomas,

    Zitat Zitat von tomson Beitrag anzeigen
    Ich möchte alle Änderungen die zwischen öffnen und schließen dieses Fensters entstanden sind löschen, wenn gewünscht.
    das ist schon eine etwas ungewöhnliche, aber auch mögliche Arbeitsweise. Wenn der Kunde das so wünscht, sollte das auch realisiert werden, wenn es im Rahmen des normalen Aufwands liegt.

    Das Problem mit dem Verwerfen der Änderungen in der VT kann vorkommen. Beim automatischen persisitieren funktioniert das nur, wenn die Datenbank auch Paging unterstützt, andernfalls werden beim Nachladen der Daten die Änderungen verworfen. Da Du das automatische Persisitieren ausgeschaltet hast, könnte jetzt folgendes passieren: Der Anwender bewegt sich in der Table innerhalb der angezeigten Daten, da sollte noch nicht passieren. Bewegt er sich aber in einen Bereich außerhalb dieser Daten, müssen die natürlich für die Tabel nachgeladen werden. Befinden sich die Daten schon in der VT (abhängig von der abgesetzten Query), sollte auch nichts passieren. Erst wenn Daten von der physikalischen Tabelle nachgeladen werden müssen, werden die vorhandenen Daten in der VT verworfen und die VT neu geladen. Dies passiert im Hintergrund und ist schlecht vom Programmierer zu beeinflussen. Man weiß ja nicht so genau, wie XDEV alles im Hintergrund behandelt. Manches ist gut dokumentiert, manches aber auch nicht. Das ganze Thema wird noch komplexer, wenn man Lazy Loading einschaltet.

    Du kannst natürlich mit mehreren Instanzen der VT arbeiten, um beim Pagen nicht die veränderten Daten zu verwerfen. Allerdings sieht der Anwender dann auch in der "Such" VT die Änderungen nicht.

    Da ich nunmal kein Freund der "komfortablen" Automatismen bin (die es in fast jeser IDE gibt), steuere ich die Datenbankzugriffe und Anzeige in der GUI selbst. Für Dein Problem senhe ich in diesem Fall eine mögliche Lösung in Form von Transaktionen mit der Datenbankverbindung. Der normale Ablauf ist dann so: Man startet die Transaktion mit der Methode beginTranaction() auf die Datenbankverbindung. Der autoCommit-Modus wird dabei ausgeschaltet und alle Veränderungen für diese Datenbankverbindung werden aufgezeichnet. Zum normalen Beenden der Verarbeitung verwendet man die Methode commit(), zum Abbrechen die Methode rollBack(). Mit der Methode isInTransaction() kann man feststellen, ob eine Transaktion für die Datenbankverbindung aktiv ist. Ob das allerdings mit den automatischen Table Optionen (Paging verwenden) auch so funktioniert, kann ich nicht vorhersagen. Solltest Du die PageNavigationBar benutzen, ist dort festgelegt, wie das Paging erfolgt. Ob sich das allerdings mit dem Tansaktionsprozess beißt, kann ich nicht sagen, sollte es aber nicht. Es könnte aber sein, dass beim Blättern die Änderungen nicht angezeigt, wohl aber beim commit() persistiert werden. Probieren geht über Studieren ... :-)

    Peter

  3. Folgende Benutzer fanden diesen Beitrag sehr hilfreich.

    tomson (24.11.2015)

  4. #3
    Registrierter Benutzer
    Registriert seit
    15.10.2015
    Beiträge
    12
    Hat mir geholfen
    3
    Positive Bewertung 1 in 1 Post
    Zitat Zitat von Peter Schneider Beitrag anzeigen
    Der normale Ablauf ist dann so: Man startet die Transaktion mit der Methode beginTranaction() auf die Datenbankverbindung. Der autoCommit-Modus wird dabei ausgeschaltet und alle Veränderungen für diese Datenbankverbindung werden aufgezeichnet. Zum normalen Beenden der Verarbeitung verwendet man die Methode commit(), zum Abbrechen die Methode rollBack(). Mit der Methode isInTransaction() kann man feststellen, ob eine Transaktion für die Datenbankverbindung aktiv ist.
    ^^ genau so möchte ich es machen! Vielen Dank. Den "save"-Befehl selbst zu schreiben ist für mich kein Problem. Nur habe ich noch nie mit Transaktionen in XDEV gearbeitet sondern immer direkt in SQL. Kannst Du mir ein Code-Schnipsel schicken? Ich weis nämlich nicht, worauf ich die Befehle isInTransaction() / rollback() etc. wirklich ausführen muss.. Das wäre Klasse!

    Grüße Thomas

  5. #4
    Open.XDEV Team Avatar von Peter Schneider
    Registriert seit
    21.11.2012
    Beiträge
    227
    Blog-Einträge
    1
    Hat mir geholfen
    4
    Positive Bewertungen 13 in 12 Posts
    Halllo Thomas,

    Zitat Zitat von tomson Beitrag anzeigen
    Ich weis nämlich nicht, worauf ich die Befehle isInTransaction() / rollback() etc. wirklich ausführen muss..
    hab's mit XDEV noch nicht gemacht. Ich habe momentan leider keine Zeit, um die Einzelheiten rauszusuchen. Aber hier die praktische Theorie mit Fake-Code:

    // hole das Connection Objekt aus dem Datenbank Objekt
    Connection conn = DataBaseObject.DataBaseConnection();
    ...
    // Starten der Transaktion
    if (!conn.isInTransaction()) {
    conn.beginTansaction();
    {
    ...
    // hier wird gearbeitet
    ...
    // Benutzer will Änderungen Rückgängig machen
    conn.rollBack();
    ...
    // Benutzer will Änderungen speichern
    conn.commit();
    ...
    // That's it

    Achtung:
    Nur mit commit() und rollBack() werden Transaktionen in der Datenbank zurückgesetzt. Wenn das fehlerhaft häufiger nicht passiert, hat man vagabundierende Transaktionen in der Datenbank. Dann hilft nur ein Backup/Restore mit entsprechenden Optionen um die Vagabunden wieder loszuwerden.

    Weiter Informationen findest Du in der XAPI JavaDoc, erreichbar über Menü|Hilfe.

    Peter
    Geändert von Peter Schneider (24.11.2015 um 16:48 Uhr) Grund: Korrektur

  6. #5
    Registrierter Benutzer
    Registriert seit
    15.10.2015
    Beiträge
    12
    Hat mir geholfen
    3
    Positive Bewertung 1 in 1 Post
    Hallo Peter, vielen Dank noch einmal für deine ausführliche Beschreibung! Ich habe es aber nun doch dabei belassen, einfach die Virtuelle Tabelle zwischenzuspeichern, sobald etwas verändert wird. Klickt der User dann auf Abbrechen und möchte somit die Änderungen verwerfen, werden die Datensätze (welche in meinem Fall alle zu einem Auftrag gehören) erst gelöscht, danach wird das Array der zwischengespeicherten Tabelle zurückgeschrieben. Nicht Ideal, da es aber zu jedem Auftrag in meiner Tabelle sowieso nur ca. 10 Datensätze gibt, reicht das vollkommen aus.

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •