Information ist alles! DBMS_APPLICATION_INFO
Zum diesem Thema hatte ich vor langer Zeit zwar schonmal ein Blog-Posting, aber ich denke, dass es ein erneutes Posting durchaus wert ist.
Es geht darum, wie Ihr dem Datenbank-Administrator - schon während der Anwendungsentwicklung helfen könnt. Mit dem PL/SQL-Paket DBMS_APPLICATION_INFO. Das ist meiner Meinung nach eins der wichtigsten PL/SQL-Pakete für jeden Entwickler - egal ob man PL/SQL, Java, .NET, PHP oder andere Programmiersprachen verwendet.
Mit DBMS_APPLICATION_INFO könnt Ihr eure Datenbanksitzung mit drei "Etiketten" versehen. Die Etikette heißen CLIENT_INFO, MODULE und ACTION. Was Ihr dort hineinschreibt, ist der Datenbank völlig egal. Die Informationen werden aber in allen Datenbank-Views, die der DBA zur Überwachung verwendet (also V$SQL, V$SESSION und andere) mit angezeigt. Dazu ein PL/SQL-Beispiel:
begin
dbms_application_info.set_client_info(
client_info => 'MEINE_PLSQL_PROZEDUR'
);
dbms_application_info.set_module(
module_name => 'MODUL 1',
action_name => 'SCHLAFEN'
);
dbms_lock.sleep(100);
dbms_application_info.set_client_info(
client_info => ''
);
dbms_application_info.set_module(
module_name => '',
action_name => ''
);
end;
/
sho err
Wenn der DBA nun (während diese Prozedur läuft), in die V$SESSION-View hineinsieht, werden diese Informationen mit angezeigt - in den Spalten CLIENT_INFO, ACTION und MODULE.
SQL> select sid, serial#, client_info, module, action
2 from v$session where username='SCOTT'
SID SERIAL# CLIENT_INFO MODULE ACTION
---------- ---------- -------------------- ---------- ----------
39 9780 MEINE_PLSQL_PROZEDUR MODUL 1 SCHLAFEN
1 Zeile wurde ausgewählt.
Man kann also sofort sehen, was eine Datenbanksitzung gerade tut. Das ist besonders wichtig, wenn Middleware im Einsatz ist, denn diese arbeitet normalerweise mit einem Connection-Pool, in dem alle Datenbanksitzungen mit dem gleichen Nutzerkonto arbeiten ... Und mit Java lässt sich DBMS_APPLICATION_INFO ebenfalls nutzen ...
:
Connection con = theDatasource.getConnection DBMS_APPLICATION_INFO();
CallableStatement cstmt_ci = con.prepareCall("{call dbms_application_info.set_client_info(?)}");
cstmt.setString(1, "JAVA_ANWENDUNG_1");
ctsmt.execute();
CallableStatement cstmt_mo = con.prepareCall("{call dbms_application_info.set_module(?,?)}");
cstmt.setString(1, "MODUL 2");
cstmt.setString(2, "JAVA BERECHNUNG");
ctsmt.execute();
:
Und mit allen anderen Programmiersprachen geht das analog. Die Nutzung dieser Informationen zieht sich übrigens durch alle Oracle-Werkzeuge - das folgende ist ein Screenshot aus dem Oracle Enterprise Manager. Dieses Werkzeug wird typischerweise vom DBA verwendet, um Informationen über die abgelaufenen SQL-Anweisungen zu erhalten. Und auch hier kann anhand MODULE und ACTION gesucht werden.
Ich kann nur wärmstens empfehlen, DBMS_APPLICATION_INFO immer und überall einzusetzen; wenn es mal später ans Tuning oder an den Betrieb der Applikation geht, wird der Aufwand doppelt und dreifach wieder zurückgezahlt - eben dadurch, dass sich Probleme schneller zuordnen und damit auch einfacher diagnostizieren lassen. Wenn Ihr das Package bislang also noch nicht genutzt habt: Fangt noch heute damit an.

Kommentare:
Man lernt nie aus, interessante Sache - vielen Dank!
Muss man die Parameter vor dem Ende der Ausführung wieder auf "leer" setzen? (siehe Codebeispiel)
Hallo,
mann muss nicht; kann aber sinnvoll sein; denn die Datenbank macht von sich aus nichts. Deine Einträge bleiben solange stehen, wie die Session existiert und solange sie nicht anderweitig überschrieben werden.
Um ein Beispiel zu nennen: APEX nutzt das Package auch intensiv und setzt nach Abschluß seiner Arbeit alles wieder auf SQL NULL.
Beste Grüße
-Carsten
Alles klar, vielen Dank. Sowas dachte ich mir schon, war mir aber nicht sicher, ob sich das nach Beendigung der Prozedur nicht direkt "erledigt" hat.
Hallo Carsten,
Wer seine Anwendungen in Java schreibt, muß nicht unbedingt die DBMS-Packages aufrufen. Oracles JDBC-Erweiterungen stellen die Methode oracle.jdbc.OracleConnection.setEndToEndMetrics() bereit, die die besprochenen Funktionen von DBMS_APPLICATION_INFO und DBMS_SESSION vereint.
Da erlaube ich mir mal etwas Werbung in eigener Sache :-), da ich mich von Deinem nunmehr zweiten Artikel zum Thema habe anspornen lassen, meinen alten Entwurf zu DBMS_SESSION auch endlich fertig zu stellen.
Ansonsten kann ich nur beipflichten: Diese einfache Methode, seine Anwendung fürs Troubleshooting zu instrumentieren, sollte jeder Entwickler beherzigen!
Viele Grüße,
Uwe
Hallo,
für die Identifizierung von z.B. Nutzern kann auch die Funktion DBMS_SESSION.SET_IDENTIFIER(varchar2); genutzt werden. Dabei wird er Wert in V$Session.client_identifier angezeigt und man kann ein Trace nur dafür einschalten.
Ralf Flatau
Kommentar veröffentlichen