1 Themenübersicht
Dieses Dokument beschreibt die Vorgehensweise zur Implementierung von Datenaktualisierungen. Es wird im Detail beschrieben, wie die Programmstruktur einer Datenaktualisierung aufgebaut ist. Außerdem werden die Unterschiede zwischen Dialog- und Hintergrund-Datenaktualisierungen erklärt.
In der Dokumentation zu der Anwendung „Datenaktualisierungen abfragen“ finden Sie weitere Informationen dazu, wie Sie Datenaktualisierungen ausführen können.
2 Voraussetzungen
Kenntnisse über die Anwendung „Entwicklungsobjekte“ und „Datenaktualisierung abfragen“ sowie über das Entwicklungsobjekt „Anwendung“.
3 Beschreibung
Datenaktualisierungen sind Anwendungen, mit denen die Daten beliebiger Business Objects verändert werden können. Jede Datenaktualisierung wird für alle Datenbanken, die die betroffenen Business Objects enthalten, ausgeführt. Verwenden Sie die Anwendung „Datenaktualisierungen abfragen“, um Datenaktualisierungen auszuführen.
Eine Datenaktualisierung wird als Anwendung in der Anwendung „Entwicklungsobjekte“ erfasst. Über das eingetragene primäre Business Object wird definiert, auf welchen Datenbanken die Datenaktualisierung ausgeführt werden soll. Das ist abhängig davon, auf welcher Datenbank das Business Object angelegt ist (OLTP-Datenbank, OLAP-Datenbank, Repository-Datenbank, Konfigurations-Datenbank). Die Datenaktualisierung muss sich jedoch nicht ausschließlich auf das angegebene Business Object beziehen. Für Datenaktualisierungen die auf OLAP-Objekten arbeiten sollte ein zum OLAP-Objekt passendes OLTP-Objekt gewählt werden.
Es gibt unterschiedliche Typen von Datenaktualisierungen:
- Hintergrund-Datenaktualisierungen sind Hintergrund-Anwendungen, die in Verarbeitungsaufträgen ausgeführt werden können.
- Parallele Datenaktualisierungen sind Hintergrund-Datenaktualisierungen, die Daten werden jedoch parallel verarbeitet. Im Allgemeinen wird durch die parallele Verarbeitung der Daten die Ausführungszeit der Datenaktualisierung deutlich reduziert.
- Dialog-Datenaktualisierungen sind Dialoganwendungen, die interaktiv vom Benutzer ausgeführt werden. Dialog-Datenaktualisierungen können vor der Ausführung Parameter vom Benutzer abfragen.
Dialog-Datenaktualisierungen sollten so selten wie möglich verwendet werden, da diese beim Ausführen manuellen Aufwand erzeugen.
Hinweis:
Wenn möglich sollten parallele Datenaktualisierungen oder Hintergrund-Datenaktualisierungen verwendet werden, da diese im Hintergrund laufen und keine Dialog-Session während der Ausführung blockieren.
Die Direkthilfe von Datenaktualisierungen sollte folgende Informationen enthalten:
- Ziele der Datenaktualisierung
- Voraussetzungen für den Lauf der Datenaktualisierung
3.1 Hintergrund-Datenaktualisierungen
Hintergrund-Datenaktualisierungen sind Hintergrund-Anwendungen mit der besonderen Verwendung „Datenaktualisierung“ oder „Datenaktualisierung im Hintergrund“. Hintergrund-Datenaktualisierungen sollten in dem Namensraum com.<Ihr Namensraum>.app.update.log liegen.
Je nach Einstellung des Feldes „Besondere Verwendung“ werden Hintergrund-Datenaktualisierungen in einem Verarbeitungsauftrag oder automatisch beim Installieren der Softwareaktualisierung ausgeführt.
Hinweis:
Hintergrund-Datenaktualisierungen sollten, wenn möglich, immer als parallele Datenaktualisierung implementiert werden. Weitere Informationen finden Sie im Abschnitt „Implementierung von parallelen Datenaktualisierungen“.
Datenaktualisierungen sollten nur einmalig ausgeführt werden müssen. Anwendungen für regelmäßige Datenkorrekturen sollten als Dialog- oder Hintergrund-Anwendungen implementiert werden, Reorganisationen als Reorganisationsanwendungen.
3.1.1 Besondere Verwendung „Datenaktualisierung“
Hintergrund-Datenaktualisierungen mit der besonderen Verwendung „Datenaktualisierung“ werden bei der Installation der Softwareaktualisierung, die diese Datenaktualisierung enthält, ausgeführt. An das System kann sich während diese Datenaktualisierungen ausgeführt werden kein Benutzer anmelden.
Dieses Verhalten hat die folgenden Vorteile:
- Die Ausführung der Datenaktualisierungen kann nicht vergessen werden.
- Die Datenaktualisierung wird ausgeführt, wenn kein Benutzer auf dem System aktiv ist.
- Die Datenaktualisierung wird sicher ausgeführt bevor eine ggf. geänderte Anwendungslogik mit den Daten arbeitet.
- Es entsteht kein Aufwand bei der Installation der Softwareaktualisierungen.
Den Vorteilen steht der Nachteil gegenüber, dass während der Ausführung der Datenaktualisierungen kein Benutzer auf dem System arbeiten kann. Das System ist bei der Installation der Softwareaktualisierung bedeutend länger nicht verfügbar.
Die besondere Verwendung „Wiederholbare Datenaktualisierung“ darf nicht mehr verwendet werden.
3.1.2 Besondere Verwendung „Datenaktualisierung im Hintergrund“
Hintergrund-Datenaktualisierungen mit der besonderen Verwendung „Datenaktualisierung im Hintergrund“ werden nicht automatisch ausgeführt, sondern müssen mithilfe der Anwendung „Datenaktualisierungen abfragen“ in einem Verarbeitungsauftrag ausgeführt werden.
Dieses Verhalten hat die folgenden Vorteile:
- Die Ausführung der Datenaktualisierungen kann zu einem beliebigen Zeitpunkt eingeplant werden.
- Die Datenaktualisierung wird im Hintergrund im normalen Betrieb ausgeführt, somit ist die Verfügbarkeit des Systems nicht eingeschränkt.
Den Vorteilen stehen die folgenden Nachteile gegenüber:
- Der Zeitpunkt, wann die Datenaktualisierung ausgeführt wird, steht nicht fest. Die Programme arbeiten bis zur Ausführung der Datenaktualisierung auf nicht korrigierten Daten.
- Die Ausführung der Datenaktualisierung wird nicht vom System erzwungen.
3.2 Dialog-Datenaktualisierungen
Dialog-Datenaktualisierungen sind Dialog-Anwendungen mit der besonderen Verwendung „Datenaktualisierung“. Dialog-Datenaktualisierungen sollten in dem Namensraum com.<Ihr Namensraum>.app.update.ui liegen.
Dialog-Datenaktualisierungen können in der Anwendung „Datenaktualisierungen abfragen“ nur einzeln und interaktiv ausgeführt werden. Dialog-Datenaktualisierungen erlauben über eine Oberfläche die Eingabe von Parametern.
Daraus ergeben sich die folgenden Vorteile:
- Bei Dialog-Datenaktualisierungen können Parameter vor der Ausführung eingegeben werden.
Auf der anderen Seite haben Dialog-Datenaktualisierungen die folgenden Nachteile:
- Dialog-Datenaktualisierungen müssen einzeln ausgeführt werden und erzeugen somit in jedem System auf dem die entsprechende Softwareaktualisierung eingespielt wird, einen relativ hohen manuellen Aufwand.
- Dialog-Datenaktualisierungen werden in einer interaktiven Session ausgeführt. Wenn die Datenaktualisierung eine lange Laufzeit hat, so kann der Browser geschlossen werden bzw. die Verbindung auf einem Timeout laufen. In diesem Fall kann der Benutzer evtl. wichtige Meldungen nicht mehr lesen.
- Für die Erfassung der Parameter müssen unter Umständen fachliche Anwender herangezogen werden, da ein Administrator die Parameter häufignicht vorgeben kann.
Wenn eine Datenaktualisierung keine Parametereingaben benötigt, dann sollte anstatt einer Dialog-Datenaktualisierung eine Hintergrund-Datenaktualisierung verwendet werden.
Bei der Wahl der aktiven Datenbank für Dialog-Datenaktualisierungen muss Folgendes beachtet werden:
- Wird OLTP als benötigte, aktive Datenbank ausgewählt, dann kann die Datenaktualisierung nur auf der Datenbank der aktuellen Session ausgeführt werden. Wenn versucht wird, eine andere verbundene OLTP-Datenbank für die Ausführung auszuwählen, wird dies mit einer Fehlermeldung verhindert.
- Wenn die Dialog-Datenaktualisierung gegen alle an dem System angeschlossenen OLTP-Datenbanken ausgeführt werden soll, dann darf nur die Repository-Datenbank als benötigte aktive Datenbank eingetragen werden.
3.3 Ausführbarkeit von Datenaktualisierungen
Eine Datenaktualisierung kann nicht ausgeführt werden, wenn das eingetragene Business Object durch eine Entwicklungsaufgabe oder durch die Installation einer Softwareaktualisierung gesperrt ist. Handelt es sich bei dem Business Object um ein Business Entity, werden auch alle zugehörigen Dependents auf eine Sperre geprüft. Bei einem Dependent wird nur dessen Sperrstatus geprüft. Diese Einschränkung ist notwendig, da in diesem Zustand keine Aussage über den Zustand der Datenbanktabellen getroffen werden kann.
Ausführung der Datenaktualisierung bei der Installation der Softwareaktualisierung
Ist die Anwendung durch eine Entwicklungsaufgabe gesperrt, kann die Datenaktualisierung nicht ausgeführt werden, da der Status nach der Ausführung nicht gespeichert wird. Somit kann nicht festgestellt werden, ob die Datenaktualisierung korrekt ausgeführt wurde.
Ist die Java-Klasse oder eine direkt verwendete Java-Klasse durch eine Entwicklungsaufgabe gesperrt, kann die Datenaktualisierung ebenfalls nicht ausgeführt werden. Die benötigte Version der Java-Klasse befindet sich in der Entwicklungsaufgabe und nicht im Dateisystem. Dadurch würde die Vorgängerversion verwendet werden und eine korrekte Ausführung der Datenaktualisierung kann nicht gewährleistet werden.
Ausführung der Datenaktualisierung in der Anwendung „Datenaktualisierungen abfragen“
Ist die Anwendung, die Java-Klasse oder deren direkt verwendeten Java-Klassen durch eine Softwareaktualisierung gesperrt, kann die Datenaktualisierung nicht ausgeführt werden.
Ist die Anwendung durch eine Entwicklungsaufgabe gesperrt, darf die Java-Klasse sowie die direkt verwendeten Java-Klassen nur in der gleichen Entwicklungsaufgabe gesperrt sein. Nur dann ist gewährleistet, dass der korrekte Klassenstand bei der Ausführung verwendet wird. Des Weiteren wird der Ausführungsstatus nicht gespeichert. Dies dient zur Erleichterung der Entwicklung einer Datenaktualisierung.
Ist die eine verwendete Java-Klasse durch eine Entwicklungsaufgabe gesperrt, kann eine Hintergrunddatenaktualisierung nur sofort auf dem aktuellen SAS ausgeführt werden. Der Benutzer muss sicherstellen, dass der aktuelle SAS den korrekten Klassenstand verwendet.
3.4 Ausführungsstatus
Nach der Ausführung einer Datenaktualisierung drückt der Ausführungsstatus den Erfolg oder Misserfolg der Ausführung aus. Der Ausführungsstatus wird gespeichert und in der Anwendung „Datenaktualisierung abfragen“ angezeigt.
Folgende Ausführungsstatus stehen zur Verfügung:
Status | Erläuterung |
State.SUCCESS | Erfolgreich gelaufen: Datenaktualisierung wurde ohne Fehler ausgeführt. |
State.ABORTED_WITH_ERROR | Mit Fehler abgebrochen: Bei der Ausführung der Datenaktualisierung ist ein Fehler aufgetreten. Der Vorgang wurde abgebrochen. Die Datenaktualisierung muss erneut ausgeführt werden. |
State.PROCESSED_WITH_ERROR | Mit Fehler gelaufen: Bei der Ausführung der Datenaktualisierung ist ein Fehler aufgetreten. Der Vorgang wurde nicht abgebrochen. |
State.NOT_CALLED | Noch nicht aufgerufen (Default): Die Datenaktualisierung wurde nicht ausgeführt. |
State.INTERNAL_ERROR | Interner nicht behandelter Fehler |
3.5 Implementierung von Hintergrund-Datenaktualisierungen
Die abstrakte Klasse com.cisag.pgm.base.CisUpdateBatchApplication ist die Basisklasse für alle Hintergrund-Datenaktualisierungen. Für jede Datenbank wird die Methode execute aufgerufen, in der die eigentlichen Aktionen erfolgen. Die Methode execute ist abstrakt und muss implementiert werden.
Das CisEnviroment steht in der Basisklasse zur Verfügung und kann verwendet werden (MessageManager, SystemManager, ObjectManager, TransactionManager).
Wenn Sie eine Hintergrund-Datenaktualisierung implementieren, prüfen Sie gründlich, ob diese nicht besser als parallele Datenaktualisierung umgesetzt werden sollte. Weitere Informationen finden Sie im Abschnitt „Implementierung von parallelen Datenaktualisierungen“.
3.5.1 Logik-Methoden der API
protected abstract short execute();
Im execute wird die Datenaktualisierung ausgeführt. Wenn das primäre Business Entity der Datenaktualisierung auf der OLTP-Datenbank liegt, so wird execute für jede OLTP-Datenbank einzeln mit einer passenden Session aufgerufen. Bei der Implementierung der execute Methode kann daher unter anderem die Dummy-Transaktion vorausgesetzt werden. Über den Rückgabewert kann der Ausführungsstatus übermittelt werden, ob die Datenaktualisierung erfolgreich gelaufen ist oder ob ein Fehler aufgetreten ist. Mit der Methode protected short getState( ) kann der bisherige Ausführungsstatus der Datenaktualisierung abfragt werden.
Die Methode protected void setMultipleAllowed(short allowed) setzt den Aufrufstatus der Datenaktualisierung. Darüber kann gesteuert werden, ob die Datenaktualisierung einmalig oder mehrmals aufgerufen werden kann. Z. B.: Wenn eine Datenaktualisierung erfolgreich läuft, dann muss diese nicht noch einmal aufgerufen werden. Tritt jedoch ein Fehler auf, so sollte es möglich sein, die Datenaktualisierung erneut auszuführen.
- Mehrfachaufruf (Default): ALLOWED
- Einmaliger Aufruf: NOT_ALLOWED
Durch die Methode protected void setParameterList(CisParameterList parameters) kann die Datenaktualisierung Laufzeitinformationen abspeichern. Der Inhalt der Liste wird gespeichert. So können z. B. im Fehlerfall Daten in der Parameterliste gespeichert werden, die beim erneuten Aufruf der Datenaktualisierung geladen und ausgewertet werden. Dadurch kann zum Beispiel bestimmt werden, wo die Datenaktualisierung fortgesetzt werden muss oder auf welcher Datenbank die Datenaktualisierung erfolgreich gelaufen ist.
Die vorher gespeicherten Daten können mit der Methode protected CisParameterList getParameterList() abgefragt werden.
3.5.2 Exemplarischer Aufbau einer Hintergrund-Datenaktualisierung
public class UPD.. extends CisUpdateBatchApplication {
public UPD..() {
}
// Ausführen der Datenaktualisierung
public short execute() {
// Status der Datenaktualisierung initialisieren
short result = STATE_SUCCESS;
setMultipleAllowed( MULTICALL_NOT_ALLOWED );
// Transaktion öffnen
byte[] tmGuid = tm.beginNew();
try {
// Code der Aktualisierung
//im Fehlerfall:
//result = STATE.ABORTED_WITH_ERROR;
//oder STATE.PROCESSED_WITH_ERROR;
//setMultipleAllowed(MULTICALL_ALLOWED);
//ende Fehlerbehandlung
tm.commit(tmGuid);
} catch (RuntimeException ex) {
tm.rollback(tmGuid);
//je nach Fehler entsprechenden Status setzen
result = STATE_ABORTED_WITH_ERROR;
//oder STATE_PROCESSED_WITH_ERROR
//oder INTERNAL_ERROR;
setMultipleAllowed(MULTICALL_ALLOWED);
}
return result;
}
}
3.6 Implementierung von parallelen Datenaktualisierungen
Eine parallele Datenaktualisierung ist eine Hintergrund-Datenaktualisierung, die in mehreren Threads ausgeführt wird. Durch diese parallele Ausführung kann Hardware besser ausgenutzt werden und die Ausführungszeit der Datenaktualisierung kann deutlich reduziert werden.
Parallele Datenaktualisierung sind für die gleicharte und unabhängige Änderungen an vielen Datensätzen besonders gut geeignet. Die Bearbeitungsreihenfolge der Datensätze kann bei einer parallelen Datenaktualisierung nicht garantiert werden. Wenn Abhängigkeiten zwischen den geänderten Datensätzen existieren oder die Bearbeitungsreihenfolge relevant ist, dann ist die Umsetzung mit einer parallelen Datenaktualisierung u.U. schwierig oder nicht sinnvoll.
Eine parallele Datenaktualisierung wird in den folgenden Phasen ausgeführt:
- Aufteilen der Daten in Blöcke (Methode start())
- Parallele Verarbeitung der Blöcke (Methode process())
- Zusammenfassen der Verarbeitungsergebnisse (Methode finish())
- Abschluss der Verarbeitung (Methode end())
Von diesen Phasen kann bei der Implementierung nicht abgewichen werden. Es können jedoch sowohl in der Methoden start() als auch in finish() beliebig Daten verändert werden.
Die abstrakte Klasse com.cisag.pgm.base.CisUpdateSubJobApplication ist die Basisklasse für alle parallelen Datenaktualisierungen. Diese Klasse erbt von der Klasse com.cisag.pgm.base.CisUpdateBatchApplication. Damit stehen Ihnen alle Funktionen der Hintergrund-Datenaktualisierung auch in der parallelen Datenaktualisierung zur Verfügung. In diesem Abschnitt wird nur die Besonderheit von parallelen Datenaktualisierungen beschrieben.
Hinweis:
Beachten Sie, dass für jede Phase und jeden Thread eine eigene Instanz der Datenaktualisierung bei der parallelen Ausführung erzeugt wird. Sie dürfen und können zwischen den Phasen und der Verarbeitung somit keine Daten über Instanzenvariablen austauschen.
Mit der Methode getParameterList() können Sie Daten zwischen den Methoden start(), finish() und end() austauschen. Beachten Sie, dass der Inhalt der Parameterliste persistent wird. Die Parameterliste muss somit in der Methode start() nicht leer sein, sondern kann die Werte der letzten Ausführung der Datenaktualisierung enthalten.
3.6.1 Aufteilen der Daten in Blöcke
Sie müssen die Methode start() überschreiben, um die zu bearbeitenden Daten in kleinere Blöcke aufzuteilen. Sie müssen je nach Anwendungsfall eine geeignete Aufteilung der Daten finden. Verwenden Sie die die Methode
void submitJob(CisUpdateSubJobParameter block);
, um einen Block zur Verarbeitung freizugeben. Verwenden Sie die Klasse CisUpdateSubJobParameter, um den Umfang des Blocks zu beschreiben. An dieser Klasse können Sie mit der Methode getParameters() in einer CisParameterList beliebige Daten hinterlegen. Teilen Sie die Daten in Blöcke die mindestens eine Ausführungszeit von mehreren Sekunden haben. Wenn die Blöcke eine zu kurze Ausführungszeit haben, so eliminiert der Overhead für die Parallelisierung den Nutzen. Wenn einzelne Blöcke eine zu lange Ausführungszeit haben, so wird der Nutzen der Parallelisierung eingeschränkt.
Möglichkeiten für die Aufteilung der Daten in Blöcke:
- Liste mit GUIDs
Die Parameterliste eines Blocks enthält eine Liste von den GUIDs, der zu ändernden Business Object Instanzen. Die Listen in den Blöcken haben eine beschränkte Größe.
Die Aufteilung in GUID-Listen ist einfach zu implementieren, kann aber abhängig von der Menge der Guids einen gewissen Overhead erzeugen.
- Aufteilung nach fachlichen Kriterien
Die Blöcke können nach fachlichen Kriterien gebildet werden, z.B. Auftragsarten, Lagerorte, Organisationen, …. Die Aufteilung nach einem fachlichen Kriterium kann zu sehr ungleichen Blockgrößen führen, wenn z.B. der Kunde nur eine Organisation verwendet.
- Aufteilung nach Zeitbereichen z.B. Quartale
Die Aufteilung der Bearbeitung nach Zeitbereichen kann insbesondere bei Bewegungsdaten sinnvoll sein. Spitzenzeiten wie beispielsweise das Weihnachtsgeschäft können jedoch auch hier zu ungleichen Blockgrößen führen.
Der Rückgabewert der Methode start() ist der Ausführungsstatus. Jeder andere Wert als State.SUCCESS bricht die weitere Verarbeitung ab. Exceptions sollten Sie im Normalfall nicht fangen, sondern weiter werfen.
Beispiel für die Implementierung von start():
short start() {
CisResultSet rs=null;
try {
final int BLOCK_SIZE = 1000;
CisList guids = new CisArrayList(BLOCK_SIZE);
CisUpdateSubJobParameter block = new CisUpdateSubJobParameter();
rs = om.getResultSet(“SELECT …”);
while (rs.next()) {
byte[] guid = rs.getGuid(1);
guids.add(guid);
if (guids.size()>=BLOCK_SIZE) {
block.getParameters().setCisList(“guids”, guids);
submitJob(block);
guids.clear();
}
}
if (guids.size()>0) {
block.getParameters().setCisList(“guids”, guids);
submitJob(block);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}finally{
if(rs!=null){
rs.close();
}
}
return CisUpdateApplicationConstants.State.SUCCESS;
}
3.6.2 Parallele Verarbeitung der Blöcke
Die Blöcke, die von der Methode start() aufgeteilt worden sind, werden in der Methode process() verarbeitet. Der Inhalt jedes Blocks wird durch eine Parameterliste beschrieben.
Jeder Block hat einen separaten Ausführungsstatus, der durch den Rückgabewert der Methode process() gesetzt wird. Jeder von SUCCESS abweichende Rückgabewert bricht die weitere Verarbeitung von Blöcken ab.
Die Parameterliste in der Klasse CisUpdateSubJobParameter kann in der Methode process() verändert werden, um Informationen an die Methode finish() zu übergeben. Mit dieser Parameterliste kann beispielsweise übergeben werden, wie viele Objekte erfolgreich bzw. mit Fehlern in diesem Block verarbeitet worden sind.
Beispiel für die Implementierung von process():
short process(CisUpdateSubJobParameter x) {
CisList guids = x.getParameters().getCisList(“guids”);
…
x.getParameters().setInt(“objects“,objectCount);
x.getParameters().setInt(“errors“,errorCount);
return CisUpdateApplicationConstants.State.SUCCESS;
}
3.6.3 Zusammenfassen der Verarbeitungsergebnisse
In der Methode finish() werden die Ergebnisse der Verarbeitung alle Blöcke zusammengefasst. Die Defaultimplementierung dieser Methode ermittelt den Status der Datenaktualisierung aus dem Verarbeitungsstatus der einzelnen Blöcke. Wenn nur ein Block einen von SUCCESS abweichenden Wert hat, so bricht die Methode finish() ab und gibt den ersten Wert der nicht SUCCESS ist zurück. Der Rückgabewert der Methode finish() wird zum Ausführungsstatus der Datenaktualisierung. Die Methode finish() wird nicht aufgerufen, wenn die Methode start() einen von SUCCESS abweichenden Rückgabewert hat.
Sie können die Methode finish() überschreiben, um eine erweiterte Fehlerbehandlung umzusetzen oder aber um nach parallelen Verarbeitung weitere Schritte der Datenaktualisierung auszuführen. Der Methode finish() werden die CisUpdateSubJobParameter aller verarbeiteten Blöcke übergeben. Die Parameterliste eines Blocks kann zusätzliche Information aus der Methode process() enthalten. In der Parameterliste kann beispielsweise angegeben sein wie viele Objekte erfolgreich bzw. mit Fehlern in diesem Block durch die Methode process() verarbeitet worden sind.
3.7 Abschluss der Verarbeitung
Die Methode end() wird bei jeder Ausführung der Datenaktualisierung am Ende aufgerufen. Die Methode kann überschrieben werden, um ggf. temporäre Daten aufzuräumen. Es kann nicht garantiert werden, dass end() immer aufgerufen wird. Wenn beispielsweise der Application-Server während der Ausführung der Datenaktualisierung beendet wird, so wird end() unter Umständen nicht mehr aufgerufen.
3.8 Implementierung von Dialog-Datenaktualisierungen
Die abstrakte Klasse com.cisag.pgm.base.UpdateApplication ist die Basisklasse für alle Dialog-Datenaktualisierungen. In dieser Klasse wird der Ablauf der Dialog-Datenaktualisierung gesteuert. Es wird jede Datenbank auf der die Datenaktualisierung laufen soll einzeln betrachtet. Zuerst wird die Methode checkPreConditions aufgerufen. Hier erfolgt die Prüfung, ob die Datenaktualisierung auf der Datenbank ausgeführt werden kann. Nach erfolgreicher Prüfung wird die Methode execute aufgerufen, in der die eigentlichen Aktionen erfolgen. Bei diesen Methoden handelt es sich um abstrakte Methoden, die implementiert werden müssen.
Ein weiterer Bestandteil dieser Basisklasse ist eine einfache Benutzeroberfläche, die einen Ausführungsbutton in der Standard-Symbolleiste und eine Beschreibung der Datenaktualisierung (Direkthilfe der Anwendung) beinhaltet. Diese Oberfläche kann beliebig erweitert werden. Dies ist zum Beispiel notwendig, wenn bestimmte Benutzereingaben notwendig sind.
Das CisEnviroment steht in der Basisklasse zur Verfügung und kann verwendet werden (MessageManager, SystemManager, ObjectManager, TransactionManager).
3.8.1 Logik-Methoden der API
protected abstract boolean checkPreConditions(byte[] databaseGuid)
In dieser Methode können die Voraussetzungen geprüft werden, ob die Datenaktualisierung auf der aktuellen Datenbank ausgeführt werden darf. Bei der übergebenen GUID handelt es sich um die Datenbank-GUID. Alle Transaktionen sollten mit dieser GUID geöffnet werden, damit die Transaktion nicht immer auf die aktive OLTP zugreift. Bsp.: tm.beginNew(databaseGuid). Nur wenn in dieser Methode alle bedingen erfüllt sind, kann die Datenaktualisierung ausgeführt werden.
protected abstract short execute( byte[] databaseGuid );
Im execute wird die Datenaktualisierung ausgeführt. Auch hier sollten alle Transaktionen mit der übergebenen Datenbank-GUID geöffnet werden. Über den Rückgabewert kann der Ausführungsstatus übermittelt werden, ob die Datenaktualisierung erfolgreich gelaufen ist oder ob ein Fehler aufgetreten ist. Den Ausführungsstatus können Sie auch mit der Methode protected void setState(short state) setzen.
Mit der Methode protected short getState( )kann der bisherige Status der Datenaktualisierung abfragt werden.
Die Methode protected void setMultipleAllowed(short allowed) setzt den Aufrufstatus der Datenaktualisierung.
Darüber kann gesteuert werden, ob die Datenaktualisierung einmalig oder mehrmals aufgerufen werden kann. Z.B.: Läuft eine Datenaktualisierung erfolgreich, so muss diese nicht noch einmal aufgerufen werden. Tritt jedoch ein Fehler auf, dann sollte es möglich sein, die Datenaktualisierung erneut auszuführen.
- Mehrfachaufruf (Default): MULTICALL_ALLOWED
- Einmaliger Aufruf: MULTICALL_NOT_ALLOWED
Durch die Methode protected void setParameterList(CisParameterList parameters)kann die Datenaktualisierung Laufzeitinformationen abspeichern. Der Inhalt der Liste wird gespeichert. So können z. B. im Fehlerfall Daten in der Parameterliste gespeichert werden, die beim erneuten Aufruf der Datenaktualisierung geladen und ausgewertet werden. Dadurch kann u. a. bestimmt werden, wo die Datenaktualisierung fortgesetzt werden muss oder auf welcher Datenbank die Datenaktualisierung erfolgreich gelaufen ist.
Die vorher gespeicherten Daten können mit der Methode protected CisParameterList getParameterList() abgefragt werden.
3.8.2 GUI-Methoden der API
protected void initUserInterface()
Anpassung/Erweiterung der Benutzeroberfläche. Die Methode der Basisklasse muss in jeden Fall aufgerufen werden (super.initUserInterface()).
protected void applyDefaults()
Bei einer Erweiterung der Benutzeroberfläche können hier bestimmte Default-Einstellungen getroffen werden.
protected void initCoolBar()
Bevor neue Actions der Standard-Symbolleiste hinzufügt werden, muss die Methode der Basisklasse aufgerufen werden (super.initCoolBar()). Nur so wird gewährleistet, dass der Ausführungsbutton richtig initialisiert wird.
protected void dataFromUi()
protected void dataToUi()
Aktualisierung der Oberfläche. Auch hier muss die Methode der Basisklasse aufgerufen werden (super.dataFromUi(), super.dataToUi()).
protected void validate()
Prüfen der Eingaben auf der angepassten Benutzeroberfläche.
3.8.3 Exemplarischer Aufbau einer Dialog-Datenaktualisierung
public class UPD.. extends UpdateApplication {
public UPD..() {
}
// Prüfungen vor dem Ausführen der Datenaktualisierung auf der
// spezifischen Datenbank
protected boolean checkPreConditions(byte[] databaseGuid) {
boolean result = true;
// Transaktion auf spezifischer Datenbank öffnen
byte[] tmGuid = tm.beginNew(databaseGuid);
try{
// weitere Prüfungen
result = true; //result = false;
} finally {
tm.rollback(tmGuid);
}
return result;
}
// Ausführen der Datenaktualisierung auf der spezifischen Datenbank
protected short execute(byte[] databaseGuid) {
// Status der Datenaktualisierung initialisieren
short result = STATE_SUCCESS;
setMultipleAllowed( MULTICALL_NOT_ALLOWED );
// Transaktion auf spezifischer Datenbank öffnen
byte[] tmGuid = tm.beginNew(databaseGuid);
try {
// Code der eigentlichen Aktualisierung
// im Fehlerfall an dieser Stelle
//(z.B. unerwartete Werte, zumeist fachliche Gründe):
//result = STATE_ABORTED_WITH_ERROR;
//oder STATE_PROCESSED_WITH_ERROR;
//setMultipleAllowed(MULTICALL_ALLOWED);
//tm.rollback(tmGuid);//je nach notwendigkeit
//ende Fehlerbehandlung für diesen Fall.
tm.commit(tmGuid);
}catch (RuntimeException ex) {
tm.rollback(tmGuid);
//je nach aufgetreten Fehler entsprechenden Status setzen
result = STATE_ABORTED_WITH_ERROR;
//oder STATE_PROCESSED_WITH_ERROR;
setMultipleAlowed(MULTICALL_ALLOWED);
//oder MULTICALL_NOT_ALLOWED
}
return result;
}
}