SlideShare ist ein Scribd-Unternehmen logo
1 von 4
Downloaden Sie, um offline zu lesen
www.javaspektrum.de 57
 DER PRAKTIKER
Wenn‘s denn sein muss
Transaktionen auf dem
Dateisystem
Torsten Michelmann, Tapan Maheshwari
Wenn die Rede auf Dateimanipulation im Kontext von Transaktionen
kommt, dann ist die weit verbreitete Meinung: lieber nicht mit Java.
Warum eigentlich nicht? Es gibt Bibliotheken, die suggerieren, dass es
geht. Was spricht also dagegen? Verschiedene Lösungsvarianten für Ja-
va SE und Java EE sind denkbar und werden vorgestellt.
Das Grundproblem

Die meisten Dateisysteme unterstützen von Haus aus kei-
ne Transaktionen, und da Java den Gedanken der Platt-
formunabhängigkeit tief in seinen Genen trägt, unterstützt das
java.io-Package dementsprechend auch keine Transaktionen
auf Dateisystemebene.
Da die Erstellung von eigenem Code zur Implementierung
von transaktionssicheren Operationen auf dem Dateisystem
einen nicht unerheblichen Aufwand nach sich ziehen würde,
sorgt ein Griff in die Open-Source-Kiste für Erleichterung: Die
bewährte und bekannte Bibliothek Transaction aus den Apa-
che Commons liefert die Basisfunktionalität für transaktionales
Dateimanagement.
DieACID (atomicity, consistency, isolation, durability)Anfor-
derungen an Transaktionen werden in dieser Bibliothek durch
die Anwendung der pessimistischen Sperrung (pessimistic lo-
cking) implementiert. Das bedeutet, dass eine Datei nur von
genau einem Prozess bearbeitet werden darf. Weitere Anfragen
nach dieser Datei werden abgewiesen. Das garantiert, dass kei-
ne konkurrierenden Änderungen auf der Datei gemacht wer-
den, fordert aber den Preis, dass keine parallele Bearbeitung an
verschiedenen, unabhängigen Teilen der Datei durchgeführt
werden dürfen. Sicher ist das Aufsplitten einer Datei in meh-
rere Dateien in einem solchen Fall ein möglicher Workaround,
aber dieser ist mit Aufwand verbunden und möglicherweise
nicht immer einfach möglich (wenn z. B. das Dateiformat ein
Binärformat ist).
Die aktuelle Version von Commons Transaction ist 1.2, und
diese ist immerhin schon drei Jahre alt, Kontinuität und Fehler-
freiheit sind aber sicher kein Makel in jenen Kreisen, die Wert
auf Transaktionen legen. Ein entscheidender Makel der Bib-
liothek ist aber, dass verteilte Transaktionen nicht unterstützt
werden. Wie dieses Problem gelöst werden
kann, wird im Folgenden gezeigt.
Anhand zweier Anforderungsszenarien
und Design-Einschränkungen werden im
Folgenden drei Lösungsvarianten des Prob-
lems der transaktionalen Verarbeitung von
Daten, die in einer Datei vorliegen, beschrie-
ben.
Beispiel-Anwendungsfall 1:
Transaktionale Verarbeitung
einer einzelnen Datei
Eine einzelne Datei mit einer sehr großen An-
zahl von Geschäftsdatensätzen muss gelesen
und satzweise verarbeitet werden. Das Verarbeiten des Daten-
satzes besteht aus den Schritten
 Datenbankeintrag anlegen,
 markieren des Datensatzes in der Datei als „prozessiert“, da-
mit ein problemloses Wiederaufsetzen ohne Doppelverarbei-
tungen möglich ist.
Der Lösungsansatz sieht die folgenden Aktivitäten vor:
 Start einer verteilten (XA-) Transaktion,
 Datensatz aus der Datei lesen und als „prozessiert“ markie-
ren,
 einfügen des Datensatzes in die Datenbank,
 Commit der Transaktion.
Beispiel-Anwendungsfall 2: Transaktionale
Verarbeitung mit mehreren Dateien
Eine Quelldatei muss gelesen, verarbeitet und transformiert
werden, danach muss pro Satz ein Eintrag in eine Datenbank
geschrieben werden sowie eine neue Datei erzeugt werden.
Am Ende der Verarbeitung muss die Quelldatei gelöscht wer-
den. Der Lösungsansatz sieht die folgenden Aktivitäten vor:
 Start einer verteilten (XA-) Transaktion,
 einlesen der Quelldatei,
 durchführen der Transformation und Erstellung der neuen
Datei sowie einfügen der Daten in eine Datenbank,
 löschen der Quelldatei,
 Commit der Transaktion.
Im Falle eines Fehlers während der Verarbeitung werden die
mittleren drei Schritte innerhalb einer Transaktion ausgeführt,
wodurch sicher gestellt ist, dass die Quelldatei erst gelöscht
wird, wenn die Zieldatei erstellt wurde und die Daten in die
Datenbank geschrieben wurden.
Abb. 1: Verwendung der Kernkomponenten der JTA (nach [JTA1.1])
JavaSPEKTRUM 2/2010
58

DER PRAKTIKER
Commons Transaction fit für verteilte
Transaktionen
Wie gesagt, unterstützt die Commons-Bibliothek Transaction
keine Two-Phase-Commit-Zugriffe. Dieser Makel verhindert die
direkte Verwendung der API zur Lösung unseres Anwendungs-
falls, gilt es doch, darin eine verteilte Transaktion unter Einbe-
ziehung einer Datei und einer Datenbank zu implementieren.
Es kann aber Abhilfe geschaffen werden: Die Java Transac-
tion API (JTA) liefert alle Interfaces, die benötigt und gemein-
hin von JDBC- und JMS-Treibern implementiert werden, um
die Einbindung in verteilte Transaktionen zu erlauben. Abbil-
dung 1 zeigt die Grundidee der JTA: Mittels einer zentralen
TransactionManager-Klasse werden XAResource-Manager-Klassen
koordiniert, damit die verteile Transaktion durchgeführt wer-
den kann. Abbildung 2 zeigt die notwendigen Methoden, die
implementiert werden wollen.
Tabelle 1 zeigt die verfügbaren Zustände, die in XAResource
Anwendung finden. Abbildung 3 zeigt nun, wie man JTA und
Commons Transaction verheiraten kann: Die Klasse FileXARe-
source stellt den ResourceManager dar und
implementiert folglich XAResource (vgl. Abb. 1),
welcher den Zugriff auf Dateien mittels der
Commons-Transaction-Klasse FileResourceMan-
ager implementiert.
Die Klasse FileXAResource.java (s. Auszüge in
Listing 1) enthält hierbei die wesentlichen Tei-
le der Implementierung. Die Aufrufreihenfol-
ge erschließt sich aus dem Sequenzdiagramm
in Abbildung 4.
Diese Variante der Implementierung hat
einen entscheidenden Nachteil: Sie ist nicht
anwendbar in Enterprise-JavaBeans (EJB), da
die Spezifikation die Verwendung von java.io
verbietet: „An enterprise bean must not use the
java.io package to attempt to access files and directories in the file
system.“ (Quelle: [JavaEJB3.0], Kapitel 20.1.2 Programming Re-
strictions).
Abb. 2: Die wichtigsten Interfaces der JTA
Konstantenname Beschreibung
XA_OK Die Vorbereitungen zur Transaktion
sind normal beendet worden
TMSUCCESS Transaktion wurde erfolgreich beendet,
der Aufrufer kann vom Transaktions-
kontext der Ressource entfernt werden
TMFAIL Beenden der Verbindung und markieren
der Transaktion als rollback-only
TMSUSPEND Aufrufer unterbricht (aber beendet nicht)
seine Verbindung mit der Transaktion
TMRESUME Aufrufer stellt die Verbindung zu einer
unterbrochenen Transaktion her
XA_RDONLY Die Transaktion ist committed und nur
noch read-only
TMJOIN Der Aufrufer verbindet sich zu einem
existierenden Transaktionskontext
Tabelle 1: Die Bedeutung der wichtigsten Konstanten der Klasse XAResource
Abb. 3: Beispiel-Implementierung
Abb. 4: Sequenzdiagramm zur Verwendung der Klasse FileXAResource
www.javaspektrum.de 59
 DER PRAKTIKER
Datenbank-Loader: die mit EJB kompatible Lösung
Welche Muster stehen für die Verarbeitung von Dateien inner-
halb eines Java EE-Containers also zur Verfügung? Wenn die
Eingangsdaten in einer Datenbank vorlägen, wäre das Problem
schon gelöst, denn normale Datenbanken sind transaktionsori-
entiert und erlauben auch verteilte Transaktionen. Die Produk-
te sind etabliert und man vertraut ihnen, dass eine Transaktion
unter Einhaltung der ACID-Regeln durchgeführt wird.
Im Vergleich zu der Lösung mit Commons Transaction hat
diese Lösung durchaus ih-
ren Charme:
 Ein mit der Datenbank
mitgelieferter Loader ist
hochgradig bzgl. Perfor-
mance optimiert.
 Alle möglichen Fehler-
situationen sind bereits
dokumentiert und im-
plementiert.
Als Nachteil ist sicher zu
nennen, dass man ein we-
nig mehr Arbeit hat, da
man temporäre Tabellen
anlegen muss, um die Da-
ten dort zu speichern, be-
vor sie dann innerhalb der
Session-Beans verarbeitet
werden können. Aber al-
le Anwendungsfälle, die
oben beschrieben wurden,
lassen sich auch mit die-
sem datenbankzentrierten
Ansatz implementieren:
...
public class FileXAResource implements XAResource {
...
public void start(Xid xid, int flags) throws XAException {
this.storedXid = xid;
if ((flags != TMJOIN) && (flags != TMNOFLAGS)) {
//flag other than TMJOIN & TMNOFLAGS are not relevant
//to start() method, TMRESUME is not implemented
throw new XAException(XAException.XAER_INVAL);
}
checkXid(xid);
int txState = 0;
try {
txState =
fileResourceManager.getTransactionState(xidToString(xid));
} catch (ResourceManagerException e) {
//Convert ResourceManagerException to appropriate XAException
throwXAException(XAException.XAER_RMERR, e);
}
if (flags == TMJOIN &&
txState == FileResourceManager.STATUS_NO_TRANSACTION) {
//can‘t join, No existing transaction with this xid
throw new XAException(XAException.XAER_NOTA);
}
if (flags == TMNOFLAGS) {
if ((txState != FileResourceManager.STATUS_NO_TRANSACTION) ||
(txState == FileResourceManager.STATUS_ACTIVE)) {
//transaction already running with this xid
throw new XAException(XAException.XAER_DUPID);
}
try {
fileResourceManager.startTransaction(xidToString(xid));
} catch (ResourceManagerException e) {
//transaction with this xid could not be started,
//convert ResourceManagerException to appropriate XAException
throwXAException(XAException.XAER_RMERR, e);
}
}
}
...
public int prepare(Xid xid) throws XAException {
checkXid(xid);
int isPrepared = ResourceManager.PREPARE_FAILURE;
try {
//check if FileResourceManager is ready for prepare
isPrepared =
fileResourceManager.prepareTransaction(xidToString(xid));
} catch (ResourceManagerException e) {
//prepare transaction activity failed,
// convert ResourceManagerException to appropriate XAException
throwXAException(XAException.XAER_RMERR, e);
}
if (isPrepared == FileResourceManager.PREPARE_FAILURE) {
//could not prepare transaction with given xid,
//hence rolling back
throw new XAException(XAException.XA_RBROLLBACK);
}
if (isPrepared == FileResourceManager.PREPARE_SUCCESS_READONLY) {
return XA_RDONLY;
}
//return OK flag when FileResourceManager is ready
// to commit the transaction
return XA_OK;
}
...
public void commit(Xid xid, boolean onePhase) throws XAException {
checkXid(xid);
try {
fileResourceManager.commitTransaction(xidToString(xid));
} catch (ResourceManagerException e) {
//if we are here then transaction commit failed.
if (onePhase) {
//If case of one-phase commit we can directly
//roll-back the transaction
try {
//transaction identified by xid to be rolled back
fileResourceManager.rollbackTransaction(xidToString(xid));
} catch (ResourceManagerException e1) { 
//exception occurred while rolling back the transaction
throwXAException(XAException.XAER_RMERR,e1);
}
throw new XAException(XAException.XA_RBROLLBACK);
//raise XAException to signal a failed commit operation
}else{
//if not onephase & commit failed, raise XAException
//to notify TX Manager
throw new XAException(XAException.XA_RBROLLBACK);
}
}
}
...
public void end(Xid xid, int flags) throws XAException {
if ((flags != TMFAIL) && (flags != TMSUCCESS)) {
//irrelevant flag found, throw an exception
throw new XAException(XAException.XAER_INVAL);
}
checkXid(xid);
if (flags == TMFAIL) {
try {
fileResourceManager.markTransactionForRollback(
xidToString(xid));
} catch (ResourceManagerException e) {
//Transaction could not be marked for rollback,
//convert ResourceManagerException to appropriate XAException
throwXAException(XAException.XAER_RMERR, e);
}
}
}
...
}
Listing 1: Die Klasse FileXAResource.java
Abb. 5: Anwendungsfall 1
mit Datenbank-Loader
JavaSPEKTRUM 2/2010
60

DER PRAKTIKER
In Abbildung 5 ist der
prinzipielle Ablauf unter
Verwendung des Daten-
banktoolings zum Laden
von Dateien gezeigt. In Ab-
bildung 6 sieht man, dass
auch die Erstellung von Da-
teien (wie in Anwendungs-
fall 2 gefordert) mit einem
sehr ähnlichen Ansatz
durchgeführt werden kann.
Der entscheidende Punkt
ist, dass man zum Erzeugen
der Datei ebenfalls auf Da-
tenbankwerkzeuge zurück-
greift. Viele Datenbanken
bieten einen Export von
Tabelleninhalten in Dateien
(zum Teil auch schon di-
rekt mit Transformation in
andere Zeichensätze, was
sehr nützlich sein kann)
mithilfe von zur Datenbank
gehörenden Tools an. Aber
selbst, wenn das nicht der
Fall ist, lässt sich mittels
einer Stored Procedure das
gewünschte Ergebnis erzielen.
Zugegeben, dieser Ansatz implementiert nicht zu 100 % die
Schritte, die im Anwendungsfall 2 beschrieben wurden, aber
das Ziel wird auf alle Fälle erreicht: Die Quelldatei wird mit
Garantie erst dann gelöscht, wenn die Daten in der Datenbank
angekommen sind und die Zieldatei erzeugt wurde.
Extract, Transform, Load (ETL)
Eine weitere mit EJB kompatible Lösungsvariante ist die Ver-
wendung eines ETL-Tools. Diese Tools erlauben zusätzlich die
Definition von Transformations- und Mappingregeln mittels
einer grafischen Oberfläche und abstrahieren auch von den da-
runter liegenden Datenbanken. Dafür erfordern sie einen we-
sentlich höheren Einarbeitungsaufwand und Mitarbeiter mit
einem neuen Skillset im Vergleich zu der auf Java basierenden
Lösung.
Erkenntnis
Die Entscheidung zwischen den Alternativen Commons Trans-
action, Datenbank- und ETL-Tools will gut überlegt sein. Jede
Lösung hat ihre Vorteile:
 Wenn kein Java EE-Server vorhanden ist, dann ist die Verwen-
dung von Commons Transaction eine gute Alternative, solange
nicht Dutzende von verschiedenen Dateien bearbeitet werden
müssen, denn dann würde ein ETL-Tool seine Überlegenheit
bei der Implementierung ausspielen.
 Wenn die Strategie eine Implementierung auf Basis von Java
EE EJBs verlangt, dann gibt es kaum einen Weg, der an einer
Implementierung mittels Datenbank-Tools zum Laden und
Entladen von Dateien vorbeiführt.
 Wenn ein Team sehr viel Erfahrung mit einem ETL-Tool hat
und auch die notwendigen Lizenzen existieren, dann ist die
Wahl der ETL-Variante sicherlich nicht verkehrt.
Die Architekturentscheidung für eine der drei Alternativen
muss die im Projekt (und den nicht-funktionalen Anforderun-
gen) definierten Rahmenbedingungen berücksichtigen. Einen
goldenen Hammer zur Lösung des Problems der transaktiona-
len Verarbeitung von Dateien gibt es nicht.
Links
[ApacheTransaction] Transaction Overview,
http://commons.apache.org/transaction/
[JavaEJB3.0] Java Specification Request 220: Enterprise
JavaBeans 3.0, http://jcp.org/en/jsr/detail?id=220
[JavaTricksBlog2010] Transactional File Access in Java,
http://myjavatricks.com/jtfs.aspx
[JTA1.1] Java Transaction API (JTA), Version 1.1,
Release: 14 February 2007
[Olson07] J. Olson, Enhance Your Apps With File System Trans-
actions, http://msdn.microsoft.com/en-us/magazine/cc163388.aspx
[XA] X/Open XA (kurz „XA“), Standard für verteilte
Transaktionen, http://de.wikipedia.org/wiki/X/Open_XA
Abb. 6: Anwendungsfall 2 unter Verwen-
dung der Datenbank-Unload-Funktionalität
Torsten Michelmann arbeitet als Master Certified
IT Architect mit den Schwerpunkten Java EE und
Middleware für IBM Global Business Services. Er be-
fasst sich intensiv mit SOA, Open-Source-Bibliotheken
und Vorgehensmodellen zur Softwareentwicklung.
E-Mail: torsten.michelmann@de.ibm.com.
Tapan Maheshwari hat mehr als 10 Jahre
Erfahrung in der Architektur und dem Design von
E-Business-Lösung mittels Java EE. Er ist ein Certified
Enterprise Architect (SCEA) und IBM Certified SOA
Solution Designer. Er arbeitet für IBM Indien als Senior
Systems Analyst.

Weitere ähnliche Inhalte

Ähnlich wie Processing files as 2 phase xa transactional resources using java

Tutorial-XML-FastInfoset-einfuehrung
Tutorial-XML-FastInfoset-einfuehrungTutorial-XML-FastInfoset-einfuehrung
Tutorial-XML-FastInfoset-einfuehrungtutorialsruby
 
MCSA 070-740 Prüfungsfragen deutsch
MCSA 070-740 Prüfungsfragen deutschMCSA 070-740 Prüfungsfragen deutsch
MCSA 070-740 Prüfungsfragen deutschholgerschmitz2011
 
Workshop zu Hibernate 3.2.2 GA
Workshop zu Hibernate 3.2.2 GAWorkshop zu Hibernate 3.2.2 GA
Workshop zu Hibernate 3.2.2 GAOliver Belikan
 
SOA Suite 11g Deep Dive
SOA Suite 11g Deep DiveSOA Suite 11g Deep Dive
SOA Suite 11g Deep Diveesentri AG
 
Domino 9 - jetzt mit integrierten Features, die das Admin-Leben leichter machen
Domino 9 - jetzt mit integrierten Features, die das Admin-Leben leichter machenDomino 9 - jetzt mit integrierten Features, die das Admin-Leben leichter machen
Domino 9 - jetzt mit integrierten Features, die das Admin-Leben leichter machenAndreas Ponte
 
Exchange Server 2019 MetaCache Database und BigFunnel
Exchange Server 2019 MetaCache Database und BigFunnelExchange Server 2019 MetaCache Database und BigFunnel
Exchange Server 2019 MetaCache Database und BigFunnelThomas Stensitzki
 
Git vs SVN - Eine vergleichende Einführung
Git vs SVN - Eine vergleichende EinführungGit vs SVN - Eine vergleichende Einführung
Git vs SVN - Eine vergleichende EinführungMario Müller
 
MongoDB - Riesige Datenmengen schemafrei verwalten
MongoDB - Riesige Datenmengen schemafrei verwaltenMongoDB - Riesige Datenmengen schemafrei verwalten
MongoDB - Riesige Datenmengen schemafrei verwaltenTobias Trelle
 
Domino Statistiken verstehen und nutzen (Teil 1) - 41. DNUG Konferenz
Domino Statistiken verstehen und nutzen (Teil 1) - 41. DNUG KonferenzDomino Statistiken verstehen und nutzen (Teil 1) - 41. DNUG Konferenz
Domino Statistiken verstehen und nutzen (Teil 1) - 41. DNUG Konferenzpanagenda
 
Exchange Server User Group Berlin | Meetup 2019-04-03
Exchange Server User Group Berlin | Meetup 2019-04-03Exchange Server User Group Berlin | Meetup 2019-04-03
Exchange Server User Group Berlin | Meetup 2019-04-03Thomas Stensitzki
 
Einfach, schnell und leistungsstark - PAVONE Espresso Workflow für Java EE
Einfach, schnell und leistungsstark - PAVONE Espresso Workflow für Java EEEinfach, schnell und leistungsstark - PAVONE Espresso Workflow für Java EE
Einfach, schnell und leistungsstark - PAVONE Espresso Workflow für Java EERolf Kremer
 
06 Software Development Guidelines der COMLINE Cloud Service Platform - CSP
06 Software Development Guidelines der COMLINE Cloud Service Platform - CSP06 Software Development Guidelines der COMLINE Cloud Service Platform - CSP
06 Software Development Guidelines der COMLINE Cloud Service Platform - CSPChristian Guenther
 
Dateisysteme und Datenbanken im Cloud Computing
Dateisysteme und Datenbanken im Cloud ComputingDateisysteme und Datenbanken im Cloud Computing
Dateisysteme und Datenbanken im Cloud ComputingLothar Wieske
 
JAX 2013: BPMN 2.0 gehört in den Werkzeugkasten JEDES Java- Entwicklers
JAX 2013: BPMN 2.0 gehört in den Werkzeugkasten JEDES Java- EntwicklersJAX 2013: BPMN 2.0 gehört in den Werkzeugkasten JEDES Java- Entwicklers
JAX 2013: BPMN 2.0 gehört in den Werkzeugkasten JEDES Java- Entwicklerscamunda services GmbH
 
TYPO3 CMS 7.0 - Die Neuerungen - pluswerk
TYPO3 CMS 7.0 - Die Neuerungen - pluswerkTYPO3 CMS 7.0 - Die Neuerungen - pluswerk
TYPO3 CMS 7.0 - Die Neuerungen - pluswerkdie.agilen GmbH
 
Something for the Cloud
Something for the CloudSomething for the Cloud
Something for the CloudESUG
 
AdminCamp 2011 Performance
AdminCamp 2011 PerformanceAdminCamp 2011 Performance
AdminCamp 2011 PerformanceUlrich Krause
 
Oracle Datenbank-Architektur
Oracle Datenbank-ArchitekturOracle Datenbank-Architektur
Oracle Datenbank-ArchitekturMarkus Flechtner
 

Ähnlich wie Processing files as 2 phase xa transactional resources using java (20)

Tutorial-XML-FastInfoset-einfuehrung
Tutorial-XML-FastInfoset-einfuehrungTutorial-XML-FastInfoset-einfuehrung
Tutorial-XML-FastInfoset-einfuehrung
 
MCSA 070-740 Prüfungsfragen deutsch
MCSA 070-740 Prüfungsfragen deutschMCSA 070-740 Prüfungsfragen deutsch
MCSA 070-740 Prüfungsfragen deutsch
 
Workshop zu Hibernate 3.2.2 GA
Workshop zu Hibernate 3.2.2 GAWorkshop zu Hibernate 3.2.2 GA
Workshop zu Hibernate 3.2.2 GA
 
SOA Suite 11g Deep Dive
SOA Suite 11g Deep DiveSOA Suite 11g Deep Dive
SOA Suite 11g Deep Dive
 
Domino 9 - jetzt mit integrierten Features, die das Admin-Leben leichter machen
Domino 9 - jetzt mit integrierten Features, die das Admin-Leben leichter machenDomino 9 - jetzt mit integrierten Features, die das Admin-Leben leichter machen
Domino 9 - jetzt mit integrierten Features, die das Admin-Leben leichter machen
 
Exchange Server 2019 MetaCache Database und BigFunnel
Exchange Server 2019 MetaCache Database und BigFunnelExchange Server 2019 MetaCache Database und BigFunnel
Exchange Server 2019 MetaCache Database und BigFunnel
 
Git vs SVN - Eine vergleichende Einführung
Git vs SVN - Eine vergleichende EinführungGit vs SVN - Eine vergleichende Einführung
Git vs SVN - Eine vergleichende Einführung
 
Transaktionssysteme
TransaktionssystemeTransaktionssysteme
Transaktionssysteme
 
MongoDB - Riesige Datenmengen schemafrei verwalten
MongoDB - Riesige Datenmengen schemafrei verwaltenMongoDB - Riesige Datenmengen schemafrei verwalten
MongoDB - Riesige Datenmengen schemafrei verwalten
 
Domino Statistiken verstehen und nutzen (Teil 1) - 41. DNUG Konferenz
Domino Statistiken verstehen und nutzen (Teil 1) - 41. DNUG KonferenzDomino Statistiken verstehen und nutzen (Teil 1) - 41. DNUG Konferenz
Domino Statistiken verstehen und nutzen (Teil 1) - 41. DNUG Konferenz
 
Reactive Programming
Reactive ProgrammingReactive Programming
Reactive Programming
 
Exchange Server User Group Berlin | Meetup 2019-04-03
Exchange Server User Group Berlin | Meetup 2019-04-03Exchange Server User Group Berlin | Meetup 2019-04-03
Exchange Server User Group Berlin | Meetup 2019-04-03
 
Einfach, schnell und leistungsstark - PAVONE Espresso Workflow für Java EE
Einfach, schnell und leistungsstark - PAVONE Espresso Workflow für Java EEEinfach, schnell und leistungsstark - PAVONE Espresso Workflow für Java EE
Einfach, schnell und leistungsstark - PAVONE Espresso Workflow für Java EE
 
06 Software Development Guidelines der COMLINE Cloud Service Platform - CSP
06 Software Development Guidelines der COMLINE Cloud Service Platform - CSP06 Software Development Guidelines der COMLINE Cloud Service Platform - CSP
06 Software Development Guidelines der COMLINE Cloud Service Platform - CSP
 
Dateisysteme und Datenbanken im Cloud Computing
Dateisysteme und Datenbanken im Cloud ComputingDateisysteme und Datenbanken im Cloud Computing
Dateisysteme und Datenbanken im Cloud Computing
 
JAX 2013: BPMN 2.0 gehört in den Werkzeugkasten JEDES Java- Entwicklers
JAX 2013: BPMN 2.0 gehört in den Werkzeugkasten JEDES Java- EntwicklersJAX 2013: BPMN 2.0 gehört in den Werkzeugkasten JEDES Java- Entwicklers
JAX 2013: BPMN 2.0 gehört in den Werkzeugkasten JEDES Java- Entwicklers
 
TYPO3 CMS 7.0 - Die Neuerungen - pluswerk
TYPO3 CMS 7.0 - Die Neuerungen - pluswerkTYPO3 CMS 7.0 - Die Neuerungen - pluswerk
TYPO3 CMS 7.0 - Die Neuerungen - pluswerk
 
Something for the Cloud
Something for the CloudSomething for the Cloud
Something for the Cloud
 
AdminCamp 2011 Performance
AdminCamp 2011 PerformanceAdminCamp 2011 Performance
AdminCamp 2011 Performance
 
Oracle Datenbank-Architektur
Oracle Datenbank-ArchitekturOracle Datenbank-Architektur
Oracle Datenbank-Architektur
 

Kürzlich hochgeladen

Slides (1) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
Slides (1) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...Slides (1) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
Slides (1) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...DNUG e.V.
 
From Zero to still Zero: Die schönsten Fehler auf dem Weg in die Cloud
From Zero to still Zero: Die schönsten Fehler auf dem Weg in die CloudFrom Zero to still Zero: Die schönsten Fehler auf dem Weg in die Cloud
From Zero to still Zero: Die schönsten Fehler auf dem Weg in die CloudOPEN KNOWLEDGE GmbH
 
Slides (2) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
Slides (2) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...Slides (2) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
Slides (2) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...DNUG e.V.
 
Rückwärts denken vorwärts handeln - Requirements Reverse Engineering bei Syst...
Rückwärts denken vorwärts handeln - Requirements Reverse Engineering bei Syst...Rückwärts denken vorwärts handeln - Requirements Reverse Engineering bei Syst...
Rückwärts denken vorwärts handeln - Requirements Reverse Engineering bei Syst...Markus Unterauer
 
FEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data Imputation
FEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data ImputationFEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data Imputation
FEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data ImputationOPEN KNOWLEDGE GmbH
 
Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...
Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...
Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...OPEN KNOWLEDGE GmbH
 

Kürzlich hochgeladen (6)

Slides (1) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
Slides (1) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...Slides (1) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
Slides (1) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
 
From Zero to still Zero: Die schönsten Fehler auf dem Weg in die Cloud
From Zero to still Zero: Die schönsten Fehler auf dem Weg in die CloudFrom Zero to still Zero: Die schönsten Fehler auf dem Weg in die Cloud
From Zero to still Zero: Die schönsten Fehler auf dem Weg in die Cloud
 
Slides (2) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
Slides (2) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...Slides (2) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
Slides (2) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
 
Rückwärts denken vorwärts handeln - Requirements Reverse Engineering bei Syst...
Rückwärts denken vorwärts handeln - Requirements Reverse Engineering bei Syst...Rückwärts denken vorwärts handeln - Requirements Reverse Engineering bei Syst...
Rückwärts denken vorwärts handeln - Requirements Reverse Engineering bei Syst...
 
FEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data Imputation
FEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data ImputationFEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data Imputation
FEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data Imputation
 
Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...
Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...
Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...
 

Processing files as 2 phase xa transactional resources using java

  • 1. www.javaspektrum.de 57  DER PRAKTIKER Wenn‘s denn sein muss Transaktionen auf dem Dateisystem Torsten Michelmann, Tapan Maheshwari Wenn die Rede auf Dateimanipulation im Kontext von Transaktionen kommt, dann ist die weit verbreitete Meinung: lieber nicht mit Java. Warum eigentlich nicht? Es gibt Bibliotheken, die suggerieren, dass es geht. Was spricht also dagegen? Verschiedene Lösungsvarianten für Ja- va SE und Java EE sind denkbar und werden vorgestellt. Das Grundproblem  Die meisten Dateisysteme unterstützen von Haus aus kei- ne Transaktionen, und da Java den Gedanken der Platt- formunabhängigkeit tief in seinen Genen trägt, unterstützt das java.io-Package dementsprechend auch keine Transaktionen auf Dateisystemebene. Da die Erstellung von eigenem Code zur Implementierung von transaktionssicheren Operationen auf dem Dateisystem einen nicht unerheblichen Aufwand nach sich ziehen würde, sorgt ein Griff in die Open-Source-Kiste für Erleichterung: Die bewährte und bekannte Bibliothek Transaction aus den Apa- che Commons liefert die Basisfunktionalität für transaktionales Dateimanagement. DieACID (atomicity, consistency, isolation, durability)Anfor- derungen an Transaktionen werden in dieser Bibliothek durch die Anwendung der pessimistischen Sperrung (pessimistic lo- cking) implementiert. Das bedeutet, dass eine Datei nur von genau einem Prozess bearbeitet werden darf. Weitere Anfragen nach dieser Datei werden abgewiesen. Das garantiert, dass kei- ne konkurrierenden Änderungen auf der Datei gemacht wer- den, fordert aber den Preis, dass keine parallele Bearbeitung an verschiedenen, unabhängigen Teilen der Datei durchgeführt werden dürfen. Sicher ist das Aufsplitten einer Datei in meh- rere Dateien in einem solchen Fall ein möglicher Workaround, aber dieser ist mit Aufwand verbunden und möglicherweise nicht immer einfach möglich (wenn z. B. das Dateiformat ein Binärformat ist). Die aktuelle Version von Commons Transaction ist 1.2, und diese ist immerhin schon drei Jahre alt, Kontinuität und Fehler- freiheit sind aber sicher kein Makel in jenen Kreisen, die Wert auf Transaktionen legen. Ein entscheidender Makel der Bib- liothek ist aber, dass verteilte Transaktionen nicht unterstützt werden. Wie dieses Problem gelöst werden kann, wird im Folgenden gezeigt. Anhand zweier Anforderungsszenarien und Design-Einschränkungen werden im Folgenden drei Lösungsvarianten des Prob- lems der transaktionalen Verarbeitung von Daten, die in einer Datei vorliegen, beschrie- ben. Beispiel-Anwendungsfall 1: Transaktionale Verarbeitung einer einzelnen Datei Eine einzelne Datei mit einer sehr großen An- zahl von Geschäftsdatensätzen muss gelesen und satzweise verarbeitet werden. Das Verarbeiten des Daten- satzes besteht aus den Schritten  Datenbankeintrag anlegen,  markieren des Datensatzes in der Datei als „prozessiert“, da- mit ein problemloses Wiederaufsetzen ohne Doppelverarbei- tungen möglich ist. Der Lösungsansatz sieht die folgenden Aktivitäten vor:  Start einer verteilten (XA-) Transaktion,  Datensatz aus der Datei lesen und als „prozessiert“ markie- ren,  einfügen des Datensatzes in die Datenbank,  Commit der Transaktion. Beispiel-Anwendungsfall 2: Transaktionale Verarbeitung mit mehreren Dateien Eine Quelldatei muss gelesen, verarbeitet und transformiert werden, danach muss pro Satz ein Eintrag in eine Datenbank geschrieben werden sowie eine neue Datei erzeugt werden. Am Ende der Verarbeitung muss die Quelldatei gelöscht wer- den. Der Lösungsansatz sieht die folgenden Aktivitäten vor:  Start einer verteilten (XA-) Transaktion,  einlesen der Quelldatei,  durchführen der Transformation und Erstellung der neuen Datei sowie einfügen der Daten in eine Datenbank,  löschen der Quelldatei,  Commit der Transaktion. Im Falle eines Fehlers während der Verarbeitung werden die mittleren drei Schritte innerhalb einer Transaktion ausgeführt, wodurch sicher gestellt ist, dass die Quelldatei erst gelöscht wird, wenn die Zieldatei erstellt wurde und die Daten in die Datenbank geschrieben wurden. Abb. 1: Verwendung der Kernkomponenten der JTA (nach [JTA1.1])
  • 2. JavaSPEKTRUM 2/2010 58  DER PRAKTIKER Commons Transaction fit für verteilte Transaktionen Wie gesagt, unterstützt die Commons-Bibliothek Transaction keine Two-Phase-Commit-Zugriffe. Dieser Makel verhindert die direkte Verwendung der API zur Lösung unseres Anwendungs- falls, gilt es doch, darin eine verteilte Transaktion unter Einbe- ziehung einer Datei und einer Datenbank zu implementieren. Es kann aber Abhilfe geschaffen werden: Die Java Transac- tion API (JTA) liefert alle Interfaces, die benötigt und gemein- hin von JDBC- und JMS-Treibern implementiert werden, um die Einbindung in verteilte Transaktionen zu erlauben. Abbil- dung 1 zeigt die Grundidee der JTA: Mittels einer zentralen TransactionManager-Klasse werden XAResource-Manager-Klassen koordiniert, damit die verteile Transaktion durchgeführt wer- den kann. Abbildung 2 zeigt die notwendigen Methoden, die implementiert werden wollen. Tabelle 1 zeigt die verfügbaren Zustände, die in XAResource Anwendung finden. Abbildung 3 zeigt nun, wie man JTA und Commons Transaction verheiraten kann: Die Klasse FileXARe- source stellt den ResourceManager dar und implementiert folglich XAResource (vgl. Abb. 1), welcher den Zugriff auf Dateien mittels der Commons-Transaction-Klasse FileResourceMan- ager implementiert. Die Klasse FileXAResource.java (s. Auszüge in Listing 1) enthält hierbei die wesentlichen Tei- le der Implementierung. Die Aufrufreihenfol- ge erschließt sich aus dem Sequenzdiagramm in Abbildung 4. Diese Variante der Implementierung hat einen entscheidenden Nachteil: Sie ist nicht anwendbar in Enterprise-JavaBeans (EJB), da die Spezifikation die Verwendung von java.io verbietet: „An enterprise bean must not use the java.io package to attempt to access files and directories in the file system.“ (Quelle: [JavaEJB3.0], Kapitel 20.1.2 Programming Re- strictions). Abb. 2: Die wichtigsten Interfaces der JTA Konstantenname Beschreibung XA_OK Die Vorbereitungen zur Transaktion sind normal beendet worden TMSUCCESS Transaktion wurde erfolgreich beendet, der Aufrufer kann vom Transaktions- kontext der Ressource entfernt werden TMFAIL Beenden der Verbindung und markieren der Transaktion als rollback-only TMSUSPEND Aufrufer unterbricht (aber beendet nicht) seine Verbindung mit der Transaktion TMRESUME Aufrufer stellt die Verbindung zu einer unterbrochenen Transaktion her XA_RDONLY Die Transaktion ist committed und nur noch read-only TMJOIN Der Aufrufer verbindet sich zu einem existierenden Transaktionskontext Tabelle 1: Die Bedeutung der wichtigsten Konstanten der Klasse XAResource Abb. 3: Beispiel-Implementierung Abb. 4: Sequenzdiagramm zur Verwendung der Klasse FileXAResource
  • 3. www.javaspektrum.de 59  DER PRAKTIKER Datenbank-Loader: die mit EJB kompatible Lösung Welche Muster stehen für die Verarbeitung von Dateien inner- halb eines Java EE-Containers also zur Verfügung? Wenn die Eingangsdaten in einer Datenbank vorlägen, wäre das Problem schon gelöst, denn normale Datenbanken sind transaktionsori- entiert und erlauben auch verteilte Transaktionen. Die Produk- te sind etabliert und man vertraut ihnen, dass eine Transaktion unter Einhaltung der ACID-Regeln durchgeführt wird. Im Vergleich zu der Lösung mit Commons Transaction hat diese Lösung durchaus ih- ren Charme:  Ein mit der Datenbank mitgelieferter Loader ist hochgradig bzgl. Perfor- mance optimiert.  Alle möglichen Fehler- situationen sind bereits dokumentiert und im- plementiert. Als Nachteil ist sicher zu nennen, dass man ein we- nig mehr Arbeit hat, da man temporäre Tabellen anlegen muss, um die Da- ten dort zu speichern, be- vor sie dann innerhalb der Session-Beans verarbeitet werden können. Aber al- le Anwendungsfälle, die oben beschrieben wurden, lassen sich auch mit die- sem datenbankzentrierten Ansatz implementieren: ... public class FileXAResource implements XAResource { ... public void start(Xid xid, int flags) throws XAException { this.storedXid = xid; if ((flags != TMJOIN) && (flags != TMNOFLAGS)) { //flag other than TMJOIN & TMNOFLAGS are not relevant //to start() method, TMRESUME is not implemented throw new XAException(XAException.XAER_INVAL); } checkXid(xid); int txState = 0; try { txState = fileResourceManager.getTransactionState(xidToString(xid)); } catch (ResourceManagerException e) { //Convert ResourceManagerException to appropriate XAException throwXAException(XAException.XAER_RMERR, e); } if (flags == TMJOIN && txState == FileResourceManager.STATUS_NO_TRANSACTION) { //can‘t join, No existing transaction with this xid throw new XAException(XAException.XAER_NOTA); } if (flags == TMNOFLAGS) { if ((txState != FileResourceManager.STATUS_NO_TRANSACTION) || (txState == FileResourceManager.STATUS_ACTIVE)) { //transaction already running with this xid throw new XAException(XAException.XAER_DUPID); } try { fileResourceManager.startTransaction(xidToString(xid)); } catch (ResourceManagerException e) { //transaction with this xid could not be started, //convert ResourceManagerException to appropriate XAException throwXAException(XAException.XAER_RMERR, e); } } } ... public int prepare(Xid xid) throws XAException { checkXid(xid); int isPrepared = ResourceManager.PREPARE_FAILURE; try { //check if FileResourceManager is ready for prepare isPrepared = fileResourceManager.prepareTransaction(xidToString(xid)); } catch (ResourceManagerException e) { //prepare transaction activity failed, // convert ResourceManagerException to appropriate XAException throwXAException(XAException.XAER_RMERR, e); } if (isPrepared == FileResourceManager.PREPARE_FAILURE) { //could not prepare transaction with given xid, //hence rolling back throw new XAException(XAException.XA_RBROLLBACK); } if (isPrepared == FileResourceManager.PREPARE_SUCCESS_READONLY) { return XA_RDONLY; } //return OK flag when FileResourceManager is ready // to commit the transaction return XA_OK; } ... public void commit(Xid xid, boolean onePhase) throws XAException { checkXid(xid); try { fileResourceManager.commitTransaction(xidToString(xid)); } catch (ResourceManagerException e) { //if we are here then transaction commit failed. if (onePhase) { //If case of one-phase commit we can directly //roll-back the transaction try { //transaction identified by xid to be rolled back fileResourceManager.rollbackTransaction(xidToString(xid)); } catch (ResourceManagerException e1) {  //exception occurred while rolling back the transaction throwXAException(XAException.XAER_RMERR,e1); } throw new XAException(XAException.XA_RBROLLBACK); //raise XAException to signal a failed commit operation }else{ //if not onephase & commit failed, raise XAException //to notify TX Manager throw new XAException(XAException.XA_RBROLLBACK); } } } ... public void end(Xid xid, int flags) throws XAException { if ((flags != TMFAIL) && (flags != TMSUCCESS)) { //irrelevant flag found, throw an exception throw new XAException(XAException.XAER_INVAL); } checkXid(xid); if (flags == TMFAIL) { try { fileResourceManager.markTransactionForRollback( xidToString(xid)); } catch (ResourceManagerException e) { //Transaction could not be marked for rollback, //convert ResourceManagerException to appropriate XAException throwXAException(XAException.XAER_RMERR, e); } } } ... } Listing 1: Die Klasse FileXAResource.java Abb. 5: Anwendungsfall 1 mit Datenbank-Loader
  • 4. JavaSPEKTRUM 2/2010 60  DER PRAKTIKER In Abbildung 5 ist der prinzipielle Ablauf unter Verwendung des Daten- banktoolings zum Laden von Dateien gezeigt. In Ab- bildung 6 sieht man, dass auch die Erstellung von Da- teien (wie in Anwendungs- fall 2 gefordert) mit einem sehr ähnlichen Ansatz durchgeführt werden kann. Der entscheidende Punkt ist, dass man zum Erzeugen der Datei ebenfalls auf Da- tenbankwerkzeuge zurück- greift. Viele Datenbanken bieten einen Export von Tabelleninhalten in Dateien (zum Teil auch schon di- rekt mit Transformation in andere Zeichensätze, was sehr nützlich sein kann) mithilfe von zur Datenbank gehörenden Tools an. Aber selbst, wenn das nicht der Fall ist, lässt sich mittels einer Stored Procedure das gewünschte Ergebnis erzielen. Zugegeben, dieser Ansatz implementiert nicht zu 100 % die Schritte, die im Anwendungsfall 2 beschrieben wurden, aber das Ziel wird auf alle Fälle erreicht: Die Quelldatei wird mit Garantie erst dann gelöscht, wenn die Daten in der Datenbank angekommen sind und die Zieldatei erzeugt wurde. Extract, Transform, Load (ETL) Eine weitere mit EJB kompatible Lösungsvariante ist die Ver- wendung eines ETL-Tools. Diese Tools erlauben zusätzlich die Definition von Transformations- und Mappingregeln mittels einer grafischen Oberfläche und abstrahieren auch von den da- runter liegenden Datenbanken. Dafür erfordern sie einen we- sentlich höheren Einarbeitungsaufwand und Mitarbeiter mit einem neuen Skillset im Vergleich zu der auf Java basierenden Lösung. Erkenntnis Die Entscheidung zwischen den Alternativen Commons Trans- action, Datenbank- und ETL-Tools will gut überlegt sein. Jede Lösung hat ihre Vorteile:  Wenn kein Java EE-Server vorhanden ist, dann ist die Verwen- dung von Commons Transaction eine gute Alternative, solange nicht Dutzende von verschiedenen Dateien bearbeitet werden müssen, denn dann würde ein ETL-Tool seine Überlegenheit bei der Implementierung ausspielen.  Wenn die Strategie eine Implementierung auf Basis von Java EE EJBs verlangt, dann gibt es kaum einen Weg, der an einer Implementierung mittels Datenbank-Tools zum Laden und Entladen von Dateien vorbeiführt.  Wenn ein Team sehr viel Erfahrung mit einem ETL-Tool hat und auch die notwendigen Lizenzen existieren, dann ist die Wahl der ETL-Variante sicherlich nicht verkehrt. Die Architekturentscheidung für eine der drei Alternativen muss die im Projekt (und den nicht-funktionalen Anforderun- gen) definierten Rahmenbedingungen berücksichtigen. Einen goldenen Hammer zur Lösung des Problems der transaktiona- len Verarbeitung von Dateien gibt es nicht. Links [ApacheTransaction] Transaction Overview, http://commons.apache.org/transaction/ [JavaEJB3.0] Java Specification Request 220: Enterprise JavaBeans 3.0, http://jcp.org/en/jsr/detail?id=220 [JavaTricksBlog2010] Transactional File Access in Java, http://myjavatricks.com/jtfs.aspx [JTA1.1] Java Transaction API (JTA), Version 1.1, Release: 14 February 2007 [Olson07] J. Olson, Enhance Your Apps With File System Trans- actions, http://msdn.microsoft.com/en-us/magazine/cc163388.aspx [XA] X/Open XA (kurz „XA“), Standard für verteilte Transaktionen, http://de.wikipedia.org/wiki/X/Open_XA Abb. 6: Anwendungsfall 2 unter Verwen- dung der Datenbank-Unload-Funktionalität Torsten Michelmann arbeitet als Master Certified IT Architect mit den Schwerpunkten Java EE und Middleware für IBM Global Business Services. Er be- fasst sich intensiv mit SOA, Open-Source-Bibliotheken und Vorgehensmodellen zur Softwareentwicklung. E-Mail: torsten.michelmann@de.ibm.com. Tapan Maheshwari hat mehr als 10 Jahre Erfahrung in der Architektur und dem Design von E-Business-Lösung mittels Java EE. Er ist ein Certified Enterprise Architect (SCEA) und IBM Certified SOA Solution Designer. Er arbeitet für IBM Indien als Senior Systems Analyst.