Die Performance im Visier

Wege der Java-Integration in Oracle 9i

09.05.2003
Java hat sich inzwischen als ein Standard zur Entwicklung von größeren Applikationen durchgesetzt. Oracles Datenbank bietet verschiedene Architekturansätze, in denen Java- beziehungsweise PL/SQL-Anwendungen laufen können. Insbesondere bei häufigem Datenzugriff ist die Wahl der richtigen Architektur entscheidend für die Performance der Gesamtanwendung. Von Rudolf Jansen*

Wer vor der Umsetzung einer Java-Datenbankanbindung steht, der wird sich im Normalfall mit dem Einsatz von Java Database Connectivity (JDBC) beschäftigen. Dabei handelt es sich um einen herstellerübergreifenden Standard, über den eine Sammlung von Java-Klassen bereitgestellt wird. Alle Datenbankzugriffe werden über Methodenaufrufe dieser Klassen realisiert. Die Umsetzung der Zugriffe auf eine konkrete Datenbank erfolgt dann erst zur Laufzeit über einen JDBC-Treiber, der sich im Classpath der Anwendung befinden muss.

Treiber und ihre Erweiterungen

Durch den Einsatz der standardkonformen JDBC-Aufrufe können Java-Anwendungen portabel programmiert werden, ein Wechsel der zugrunde liegenden Datenbank zu einem späteren Zeitpunkt ist durch Austausch des entsprechenden JDBC-Treibers möglich. Oracle bietet für die hauseigene Datenbank zusätzlich zu diesen standardkonformen JDBC-Klassen eine Reihe von JDBC-Erweiterungen an, die auf die speziellen Gegebenheiten der Oracle-Datenbank zugeschnitten sind (zum Beispiel auf den Umgang mit Oracle-eigenen Datentypen) und daher eine Performance-Steigerung gegenüber Standard-JDBC versprechen.

Als Alternative zum Einsatz von JDBC existiert der SQLJ-Standard. Dieser ist wesentlich weniger bekannt als JDBC, bietet aber insbesondere in der Entwicklungsphase eines Projekts einige Vorteile gegenüber JDBC. SQLJ ist ebenfalls ein herstellerunabhängiger Standard, der sich an der Vorgehensweise der Precompiler aus anderen Programmiersprachen orientiert: Vor dem eigentlichen Compiler-Lauf werden die im Sourcecode enthaltenen Datenbankzugriffe durch den Precompiler auf Syntax- und Semantikfehler (etwa fehlende Zugriffsrechte) überprüft und anschließend in JDBC-Code übertragen. Fehler innerhalb der Datenbankzugriffe werden bei SQLJ also bereits zur Entwicklungszeit entdeckt, während JDBC-Anwendungen solche Fehler erst zur Laufzeit offen legen.

Flaschenhals im Gesamtsystem

Der bei JDBC- und SQLJ-Anwendungen zur Laufzeit erforderliche Netzwerkzugriff auf die meist auf einem anderen Rechner installierte Datenbank erweist sich in vielen Anwendungen als ein möglicher Performance-Engpass für das Gesamtsystem. Insbesondere für datenintensive Anwendungen wird daher häufig nach einer Möglichkeit gesucht, diesen Netzwerkzugriff zu vermeiden und die Applikationslogik dort laufen zu lassen, wo auch die Daten liegen, nämlich direkt in der Datenbank.

Für Entwickler von Oracle-Anwendungen bietet sich dafür der Einsatz der Sprache PL/SQL an. PL/SQL ist eine prozedurale Spracherweiterung zu SQL, mit der eine datennahe Verarbeitung direkt mit den SQL-Datentypen möglich ist. Die Umwandlung von SQL-Datentypen in die anderer Programmiersprachen entfällt also beim Einsatz von PL/SQL. Im Vergleich zu Java besitzt PL/SQL allerdings nicht so mächtige Application Programming Interfaces (APIs). Anbindungen an externe Systeme etwa über Mail-Transfer, Dateizugriffe oder XML-Parsing lassen sich über Java-Standardklassen oder eine der zahlreichen Java-Erweiterungen wesentlich bequemer realisieren. Gesucht ist für den Bereich Datenbankentwicklung also ein goldener Mittelweg zwischen einer externen Java-Anwendung und einer internen PL/SQL-Applikation.

Einen solchen Mittelweg stellt Oracle mit der Integration einer Java Virtual Machine (JVM) im Kern der Datenbank zur Verfügung. Beginnend mit der Version 8.1.5 stellt diese JVM zunächst unter der Bezeichnung Jserver Unterstützung für das JDK 1.1.6 bereit. Ab Release 8.1.6 können die JDK-1.2.1-Funktionen eingesetzt werden. In der neuesten Datenbankversion 9i, Release 2, wird nun das JDK 1.3 unterstützt. Die JVM von Oracle 9i stellt allerdings nur noch Funktionen der Java 2 Standard Edition (J2SE) bereit. J2EE-Funktionen (Java 2 Enterprise Edition) sind somit auf die Application-Server-Schicht beschränkt. Zentraler Bestandteil der Oracle 9i JVM ist das Tool "loadjava", mit dem sowohl Java-Sourcen als auch extern vorcompilierte Klassen in die Datenbank geladen werden können. Das Werkzeug ist Bestandteil der Standardinstallation der Oracle-Datenbank.

Wer sich bisher nur mit normalen externen Java-Anwendungen beschäftigt hat, wird sich zunächst fragen, wie die Java-Klassen in der Datenbank abgelegt und von dort aufgerufen werden können. Innerhalb der Datenbank existiert kein Dateisystem, das bei externen Anwendungen als Ablage für Java-Klassen sowie innerhalb des Java-Classpath als Verzeichnis für referenzierte Java-Klassen verwendet werden kann. Stattdessen werden Java-Sourcen und Java-Klassen als Datenbank-Schemaobjekte angelegt. Als Classpath-Ersatz dient das Resolving-Konzept, über das beim Aufruf einer Java-Klasse Datenbankschemata angegeben werden können, in denen referenzierte Java-Klassen gesucht werden.

Der Aufruf von datenbankinternen Java-Anwendungen erfolgt über Java Stored Procedures. Dies sind PL/SQL-Prozeduren, über die statische Methoden aus Java-Klassen aufgerufen werden können, die sich im Schema des aufrufenden Datenbank-Users befinden. Sowohl die Rechte zum Ausführen dieser Java Stored Procedures als auch die Rechte, unter denen die Anwendung läuft (Zugriff auf Betriebssystem-Ressourcen etc.), können feingranular vergeben werden.

Plattformunabhängigkeit geht verloren

Alle Java-Systemklassen liegen vorcompiliert in nativem Maschinencode in der Datenbank vor. Auch selbst geschriebene Anwendungen können zur Performance-Steigerung in ein solches natives Format gebracht werden. Der bekannte Java-Vorteil der Plattformunabhängigkeit geht zwar dadurch verloren, er spielt aber aufgrund der Tatsache, dass die Java-Anwendung innerhalb der Datenbank in einer fest vorgegebenen Systemumgebung abläuft, keine große Rolle.

Welcher Architekturansatz sollte also bei der Erstellung einer Java-Oracle-Anwendung gewählt werden? Bei datenintensiven Anwendungen kann PL/SQL seine Performance-Vorteile durch die nicht erforderliche Typumwandlung ausspielen, da hierbei die gleichen Datentypen wie in der Datenbank verwendet werden. Wer dagegen die mächtigen Java-APIs der J2SE einsetzen will, gleichzeitig aber den möglichen Performance-Engpass durch einen Netzwerkzugriff von einer externen Java-Anwendung auf die Datenbank umgehen möchte, der sollte den Einsatz der datenbankinternen JVM in Erwägung ziehen. Ein weiteres Kriterium für die Wahl zwischen Java und PL/SQL ist das erforderliche Know-how in der Entwicklergruppe des Projekts.

Eine klare Trennung zwischen einer externen Java-Anwendung und der Datenbank erlaubt auch eine solche Trennung innerhalb der Entwicklergruppe: Die Java-Programmierer benötigen kein spezielles Datenbank-Know-how, und die Datenbankspezialisten können sich auf die Optimierung des Datenbankschemas konzentrieren. Der Einsatz von Java in der Datenbank erfordert aber Java- und Datenbankkenntnisse bei allen beteiligten Entwicklern. (ue)

*Rudolf Jansen ist freiberuflicher Softwareentwickler in Aachen.

Literatur

Java und XML sind inzwischen zu Standards in Enterprise-Projekten geworden. Oracle 9i bietet eine robuste Integration dieser Techniken. Der Autor beleuchtet die Java- und XML-Fähigkeiten der Datenbank sowie deren unterschiedliche Architekturansätze. Insbesondere die mit Version 9i, Release 2, eingeführten Features zur XML-Integration werden als vielversprechend bezeichnet. Das seit April verfügbare Buch setzt Grundkenntnisse zu den genannten Themen voraus.

Rudolf Jansen: Oracle, Java, XML: Integration in Oracle 9i, Architekturansätze für die Praxis.

Frankfurt/Main: Software&Support-Verlag 2003. 360 Seiten, 39,90 Euro.

Abb: Integrierte Architektur

Java Stored Procedures rufen die als Schemaobjekte hinterlegten Java-Klassen auf. Quelle: Jansen