In diesem Blog Posting möchte ich euch eines der besser gehüteten Geheimnisse der Oracle-Datenbank
vorstellen: den Workspace Manager. Das ist eine kaum bekannte, aber sehr mächtige Technologie, mit
der Ihr auf einer Tabelle "langlaufende Transaktionen" (also "Transaktionen" über mehrere Datenbanksessions hinweg) ausführen könnt. Doch was ist eine
"langlaufende Transaktion" ...?
- T0: Die langlaufende Transaktion startet
- T1: Es wird eine SQL-Anweisung (INSERT, UPDATE, DELETE) ausgeführt
- T2: Commit und Schließen der Datenbanksession
- T3: Neue Datenbanksession: Es wird noch eine SQL-Anweisung (INSERT, UPDATE, DELETE) ausgeführt
- T4: Commit
- T5: Die gesamte langlaufende Transaktion wird zurückgerollt - die Tabelle ist auf dem Stand T0
Solche langlaufenden Transaktionen werden oft für Planungen oder
Simulationen benötigt. Solche Prozesse dauern dann oft mehrere Tage, Wochen oder
gar Monate. Mit den "normalen" Datenbanktransaktionen lässt sich so etwas gar nicht
umsetzen - die Datenbanksitzung müsste ja genauso lange offenbleiben. Workspace Manager
erlaubt nun "Transaktionen" für solch lange Zeiträume mitsamt dem Verwerfen oder Übernehmen
der gesammelten Änderungen als Ganzes. Und der Workspace Manager ist Teil der Standard-Edition. Darüber hinaus
erlaubt der Workspace Manager mehrere Workspaces - so können zur gleichen Zeit
unterschiedliche Planungen bzw. Simulationen in der Datenbank vorliegen.
Die langlaufende Transaktion wird hier
mit den Mitteln der Datenbank, also mit Tabellen, Views, Triggern und PL/SQL realisiert. In diesem
Blog-Posting werde ich damit beginnen, den Workspace Manager zu beschreiben. Allerdings
werde ich nicht alles auf einmal schaffen, das hier ist also Teil 1. In einem zweiten
Teil werde ich dann weitere Features und Konzepte des Workspace Manager beschreiben.
Am besten wird es nun sein, wenn ich gleich mit einem Beispiel starte ...
1. Tabelle(n) für den Workspace Manager einrichten
Die Tabellen, auf denen man mit dem Workspace Manager arbeiten möchte,
müssen zuerst aktiviert werden - das nennt man Version-Enabling, und es geschieht mit einem Aufruf von DBMS_WS.ENABLEVERSIONING.
begin dbms_wm.enableVersioning('EMP,DEPT'); end; /
Wenn sich Tabellen per Fremdschlüsselbeziehung beziehen, müssen diese ggfs. gemeinsam
in ein- und demselben Aufruf von DBMS_WM.ENABLEVERSIONING aktiviert werden. Wird die
zu aktivierende Tabelle
von anderen Tabellen referenziert, ist sie also eine Parent-Tabelle, so müssen alle
Child-Tabellen im gleichen Aufruf mit aktiviert werden. Ist die zu aktivierende Tabelle
dagagen eine Child-Tabelle, so kann man die Parent-Tabelle mit aktivieren, man muss es aber nicht.
Im Beispiel DEPT und EMP kann also die EMP-Tabelle alleine
oder die Tabellen EMP und DEPT gemeinsam für den Workspace Manager aktiviert werden.
Das Version-Enabling einer Tabelle hat ein paar Konsequenzen. So muss man bei
DDL-Anweisungen (ALTER TABLE) auf diese Tabelle künftig aufpassen. Bevor man ein
ALTER TABLE absetzen kann, muss mit DBMS_WM.BEGIN_DDL eine DDL-Session gestartet werden. Mit
DBMS_WM.COMMIT_DDL wird diese beendet. Das gleiche gilt für Bulk-Loading-Vorgänge.
Wenn man sich nun im Datenbankschema umsieht, stellt man fest, dass sich einiges
getan hat.
SQL> select * from tab where tname like 'EMP%'; TNAME TABTYPE CLUSTERID ------------------------------ ------- ---------- EMP VIEW EMP_AUX TABLE EMP_BASE VIEW EMP_BPKC VIEW EMP_CONF VIEW EMP_CONS VIEW EMP_DIFF VIEW EMP_LOCK VIEW EMP_LT TABLE EMP_MW VIEW EMP_PKC VIEW EMP_PKD VIEW EMP_PKDB VIEW EMP_PKDC VIEW
Die eigentliche Tabelle EMP wurde umbenannt in EMP_LT - außerdem enthält sie nun
einige zusätzliche Spalten für den Workspace Manager.
SQL> desc emp_lt
Name Null? Typ
----------------------------------------- -------- -------------------------
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)
VERSION NUMBER(38)
NEXTVER VARCHAR2(500)
DELSTATUS NUMBER(38)
LTLOCK VARCHAR2(100)
Das Objekt EMP gibt es aber nach wie vor - den Platz der Tabelle hat nun allerdings
eine View übernommen. DML-Operationen finden nun auf der View statt - und die INSTEAD OF Trigger
der View sorgen dafür, dass die Tabelle EMP_LT mitsamt der Information über Version
und Workspace korrekt aktualisiert wird. Das wollen wir gleich ausprobieren ...
2. Einen Workspace einrichten und Daten ändern
Jetzt, wo wir den Workspace Manager verwenden, müssen wir auch "in Workspaces denken". Der
"Normalzustand" der Tabelle ist der Workspace LIVE. Das ist der Änderungsstand, den alle
Datenbanksessions sehen. Änderungen am Workspace LIVE sind auch ohne weiteres für alle
anderen Sessions sichtbar - also öffentlich. Für eine "private" Planung bzw. Simulation
brauchen wir zuerst einen neuen Workspace. Wir legen also mit
DBMS_WM.CREATEWORKSPACE den Workspace PLANUNG_1 in der Hierarchie unterhalb
von LIVE an.
begin dbms_wm.createWorkspace('PLANUNG_1'); end; /
Danach in den neuen Workspace mit DBMS_WM.GOTOWORKSPACE wechseln ...
begin dbms_wm.gotoWorkspace('PLANUNG_1'); end; /
Ist man sich nicht sicher, in welchem Workspace man sich gerade befindet, schafft
die Funktion DBMS_WM.GETWORKSPACE Abhilfe.
SQL> select dbms_wm.getworkspace from dual; GETWORKSPACE ------------------------------------------------- PLANUNG_1
Nun kann man einige Änderungen machen ... das COMMIT dabei nicht vergessen ...
SQL> update emp set sal = sal * 2 where deptno = 20; SQL> delete from emp where job = 'SALESMAN'; SQL> commit; SQL> select * from emp order by deptno; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ----- ---------- --------- ----- ------------------- ----- ----- ------ 7934 MILLER CLERK 7782 23.01.1982 00:00:00 1300 10 7839 KING PRESIDENT 17.11.1981 00:00:00 5000 10 7782 CLARK MANAGER 7839 09.06.1981 00:00:00 2450 10 7902 FORD ANALYST 7566 03.12.1981 00:00:00 6000 20 7369 SMITH CLERK 7902 17.12.1980 00:00:00 1600 20 7566 JONES MANAGER 7839 02.04.1981 00:00:00 5950 20 7876 ADAMS CLERK 7788 12.01.1983 00:00:00 2200 20 7788 SCOTT ANALYST 7566 09.12.1982 00:00:00 6000 20 7900 JAMES CLERK 7698 03.12.1981 00:00:00 950 30 7698 BLAKE MANAGER 7839 01.05.1981 00:00:00 2850 30 10 Zeilen ausgewählt.
Sieht aus, wie immer, oder? Aber das ist dennoch ein privater Bereich, wie man
mit einem schnellen Wechsel des Workspace leicht feststellen kann.
begin dbms_wm.gotoWorkspace('LIVE'); end; / SQL> select * from emp order by deptno; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ----- ---------- --------- ----- ------------------- ----- ----- ------ 7782 CLARK MANAGER 7839 09.06.1981 00:00:00 2450 10 7839 KING PRESIDENT 17.11.1981 00:00:00 5000 10 7934 MILLER CLERK 7782 23.01.1982 00:00:00 1300 10 7566 JONES MANAGER 7839 02.04.1981 00:00:00 2975 20 7902 FORD ANALYST 7566 03.12.1981 00:00:00 3000 20 7876 ADAMS CLERK 7788 12.01.1983 00:00:00 1100 20 7369 SMITH CLERK 7902 17.12.1980 00:00:00 800 20 7788 SCOTT ANALYST 7566 09.12.1982 00:00:00 3000 20 7521 WARD SALESMAN 7698 22.02.1981 00:00:00 1250 500 30 7844 TURNER SALESMAN 7698 08.09.1981 00:00:00 1500 0 30 7499 ALLEN SALESMAN 7698 20.02.1981 00:00:00 1600 300 30 7900 JAMES CLERK 7698 03.12.1981 00:00:00 950 30 7698 BLAKE MANAGER 7839 01.05.1981 00:00:00 2850 30 7654 MARTIN SALESMAN 7698 28.09.1981 00:00:00 1250 1400 30 14 Zeilen ausgewählt.
Im LIVE Workspace befindet sich immer noch der "alte" Zustand der Tabelle EMP.
Dieser Zustand bleibt auch bestehen, wenn man die Datenbanksession schließt. Auch
eine neue Datenbanksession befindet sich zunächst im Workspace LIVE; sieht in unserem
Beispiel also die "normalen" Inhalte der Tabelle EMP. Nach einem
Wechsel in den Workspace PLANUNG_1 kann man mit der Simulation weitermachen ...
begin dbms_wm.gotoWorkspace('PLANUNG_1'); end; / SQL> select * from emp order by deptno; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ----- ---------- --------- ----- ------------------- ----- ----- ------ 7934 MILLER CLERK 7782 23.01.1982 00:00:00 1300 10 7839 KING PRESIDENT 17.11.1981 00:00:00 5000 10 7782 CLARK MANAGER 7839 09.06.1981 00:00:00 2450 10 7902 FORD ANALYST 7566 03.12.1981 00:00:00 6000 20 7369 SMITH CLERK 7902 17.12.1980 00:00:00 1600 20 7566 JONES MANAGER 7839 02.04.1981 00:00:00 5950 20 7876 ADAMS CLERK 7788 12.01.1983 00:00:00 2200 20 7788 SCOTT ANALYST 7566 09.12.1982 00:00:00 6000 20 7900 JAMES CLERK 7698 03.12.1981 00:00:00 950 30 7698 BLAKE MANAGER 7839 01.05.1981 00:00:00 2850 30 10 Zeilen ausgewählt.
3. Noch mehr Workspaces anlegen ...
Unterhalb des Workspace PLANUNG_1 kann nun noch ein neuer Workspace erstellt
werden; wenn im Rahmen einer Planung beispielsweise mehrere "Untervarianten"
durchgespielt werden sollen.
SQL> select dbms_wm.getworkspace from dual; GETWORKSPACE ------------------------------------------------- PLANUNG_1 begin dbms_wm.createWorkspace('PLAN_1_VARIANTE_A'); end; / begin dbms_wm.createWorkspace('PLAN_1_VARIANTE_B'); end; /
Es lässt sich also eine ganze Hierarchie von Workspaces aufbauen. Und alle Änderungen
in einem Workspace sind für diesen Workspace privat. Wir wechseln also in den
Workspace PLAN_1_VARIANTE_A und nehmen dort nochmals eine Änderung vor.
begin dbms_wm.gotoWorkspace('PLAN_1_VARIANTE_A'); end; / SQL> delete from emp where sal > 3000; SQL> commit; SQL> select * from emp order by deptno; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ----- ---------- --------- ----- ------------------- ----- ----- ------ 7782 CLARK MANAGER 7839 09.06.1981 00:00:00 2450 10 7934 MILLER CLERK 7782 23.01.1982 00:00:00 1300 10 7369 SMITH CLERK 7902 17.12.1980 00:00:00 1600 20 7876 ADAMS CLERK 7788 12.01.1983 00:00:00 2200 20 7698 BLAKE MANAGER 7839 01.05.1981 00:00:00 2850 30 7900 JAMES CLERK 7698 03.12.1981 00:00:00 950 30 6 Zeilen ausgewählt.
Nun befinden sich drei Varianten der Tabelle EMP in der Datenbank. Der Workspace LIVE
enthält die Originaldaten, in PLANUNG_1 befindet sich eine Änderung (die Tabelle hat hier 10 Zeilen)
und in PLAN_1_VARIANTE_A gibt es eine Tabellenversion mit 6 Zeilen. Tatsächlich sind natürlich alle Versionen
in der Tabelle EMP_LT gespeichert - die View EMP zeigt - je nach Workspace - unterschiedliche Dinge an.
Doch am nächsten Tag stellen wir fest: Wir brauchen im
Workspace PLAN_1_VARIANTE_A wieder den Originalstand aus dem Workspace PLANUNG_1. Dazu
gibt es das Kommando DBMS_WS.ROLLBACKWORKSPACE.
4. Workspace Merge und Workspace Rollback
begin dbms_wm.rollbackWorkspace('PLAN_1_VARIANTE_A'); end; / SQL> select * from emp order by deptno; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ----- ---------- --------- ----- ------------------- ----- ----- ------ 7934 MILLER CLERK 7782 23.01.1982 00:00:00 1300 10 7839 KING PRESIDENT 17.11.1981 00:00:00 5000 10 7782 CLARK MANAGER 7839 09.06.1981 00:00:00 2450 10 7902 FORD ANALYST 7566 03.12.1981 00:00:00 6000 20 7369 SMITH CLERK 7902 17.12.1980 00:00:00 1600 20 7566 JONES MANAGER 7839 02.04.1981 00:00:00 5950 20 7876 ADAMS CLERK 7788 12.01.1983 00:00:00 2200 20 7788 SCOTT ANALYST 7566 09.12.1982 00:00:00 6000 20 7900 JAMES CLERK 7698 03.12.1981 00:00:00 950 30 7698 BLAKE MANAGER 7839 01.05.1981 00:00:00 2850 30 10 Zeilen ausgewählt.
Soll eine Planung nicht verworfen, sondern - im Gegenteil - in den Parent-Workspace übernommen werden,
so findet eine Merge-Operation statt (DBMS_WM.MERGEWORKSPACE). Angenommen, der Zustand
im Workspace PLANUNG_1 soll zur neuen "Realität" werden, also in den LIVE-Workspace
übernommen werden - das geschieht wie folgt.
begin dbms_wm.mergeWorkspace('PLANUNG_1'); end; /
Eine Merge-Operation findet immer vom Child zum Parent statt. Da das Parent
von PLANUNG_1 der LIVE-Workspace ist, werden die Änderungen damit öffentlich. Natürlich
kann ein Merge auch tiefer in der Hierarchie stattfinden.
Für heute soll es das sein. Der Workspace Manager hat natürlich noch viele weitere, wichtige
Themen, die ich allerdings auf Teil 2 verschieben muss.
- Wie kommen Änderungen im Parent Workspace (bspw. LIVE) in den Child Workspace (Refresh)?
- Was passiert bei Konflikten (Merge in den Workspace LIVE, dort wurden aber ebenfalls Zeilen verändert)?
- Was sind Savepoints?
- Gibt es ein Privilegienmodell für den Workspace Manager?
- Gibt es eine Historisierung?
- ...
Bis dahin verweise ich auf folgendes Material zum Weiterlesen ...
- Oracle Dokumentation: Workspace Manager Developers' Guide
http://docs.oracle.com/cd/E11882_01/appdev.112/e11826/toc.htm - Workspace Manager und APEX in der APEX Community - Teil I
http://www.oracle.com/webfolder/technetwork/de/community/apex/tipps/wm/index.html - Workspace Manager und APEX in der APEX Community - Teil II
http://www.oracle.com/webfolder/technetwork/de/community/apex/tipps/wm2/index.html