23. Januar 2013

Oracle Workspace Manager: Transaktionen über mehrere Commits, Rollbacks und Sessions

Transactions spanning multiple Commits and Sessions: Workspace Manager
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 ...
In this blog posting I'd like to talk a bit about Workspace Manager, which seems to be one of the "top secret features" of the Oracle database - most users don't even know that it exists. And its an extremely powerful one: You can have table changes over a longer period of time and over multiple database sessions and the ability to commit or rollback all these changes as a whole at a specific point in time. And all this is part of the databases' Standard Edition. Workspace Manager uses the term "long running transaction" ...
  • T0: A long running transaction starts
  • T1: DML commands (INSERT, UPDATE, DELETE) are being executed
  • T2: Commit and close of the database session
  • T3: A new session starts and more DML commands are being executed
  • T4: Again: Commit
  • T5: Now the whole long-running transaction is rolled back. The table now contains the data as of timestamp T0
These long running transactions could be used for simulations or planning processes. If a plan is being discarded, the whole long running transaction is rolled back. Multiple Workspaces can contain different simulations at the same time.
If a plan is taken "to production", the changes will be visible to everyone. Such functionality (of course) cannot be achieved with "normal" database transactions: The client would need to keep the database session open all the time - and such planning processes typically take days, weeks or even months. And what if multiple database sessions want to work on the same plan ...?
So we need Workspace Manager. The long running transaction is being implemented using database technology like Tables, Views, Triggers and PL/SQL. In this blog posting I'll introduce Workspace Manager and describe its basic usage - so this will be "Part 1". More advanced features will be covered in Part 2 - which I'll publish in the future. More detailed information can be found within the Oracle Documentation. I'll start, as always, with an example ...

1. Configuring (Version-Enabling) Tables for Workspace Manager

In order to use Workspace Manager, the table must be version enabled beforehand. This is done by calling the PL/SQL procedure DBMS_WS.ENABLEVERSIONING
begin
  dbms_wm.enableVersioning('EMP,DEPT');
end;
/
Multiple tables are being passed as one argument - separated by commas. If tables are linked together using referential integrity, they might need to be version-enabled together - in one call. If the table, which is to be version-enabled, has child tables, these child tables must also be version-enabled. If the table itself is a child table, the parent table can be also version-enabled, but this is not mandatory. So for the well-known tables EMP and DEPT we can either version-enable only EMP or both EMP and DEPT. It's not possible to version-enable only DEPT, since EMP is DEPT's child table.
Version-Enabling a table has some consequences for future operations on that table. For DDL commands (ALTER TABLE) it's now required to start a DDL session with DBMS_WM.BEGIN_DDL beforehand. The DDL session is being finished with DBMS_WM.COMMIT_DDL. The same applies to Bulk-Loading processes.
Now, after version-enabling the table, we'll have a look into the database schema to see what changed.
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
The original table EMP was renamed to EMP_LT - and the table was extended by some additional columns. Workspace Manager uses these columns to store internal information.
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)
But there is still an object named EMP: A view now represents the table. And each DML command now will be captured by the views' INSTEAD OF triggers, which propagate the change to the underlying table EMP_LT and which maintain version and workspace information.

2. Create a Workspace and do some changes on EMP

Now the table EMP is under control of Workspace Manager. One workspace is already there: LIVE represents the public state - changes within the LIVE workspace will be immediately visible to everyone. The LIVE workspace typically contains production data. Simulations or planning processes are being done in separate workspaces. So we first need a new workspace: DBMS_WM.CREATEWORKSPACE creates one (here: PLAN_1) as child of the current workspace.
begin
  dbms_wm.createWorkspace('PLAN_1');
end;
/
Then change to the new workspace with DBMS_WM.GOTOWORKSPACE ...
begin
  dbms_wm.gotoWorkspace('PLAN_1');
end;
/
DBMS_WM.GETWORKSPACE shows the current workspace of your database session.
SQL> select dbms_wm.getworkspace from dual;

GETWORKSPACE
-------------------------------------------------
PLAN_1
Now we can execute DML on the table EMP - think about this as a new company "simulation" ...
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 rows selected. 
Looks as usual, doesn't it ...? But when we change the workspace again, we can see that these changes are only visible in their workspace (PLAN_1).
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 rows selected.
LIVE still contains the "original" table data. And closing and re-opening the database session has no effect on this. The new database session will start in the LIVE workspace - after changing to the PLAN_1 workspace we can continue our simulation ...
begin
  dbms_wm.gotoWorkspace('PLAN_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 rows selected.

3. Even more Workspaces

We can create additional workspaces as child workspaces under PLAN_1. This is useful, if you like to play with more than one simulation variant ...
SQL> select dbms_wm.getworkspace from dual;

GETWORKSPACE
-------------------------------------------------
PLAN_1

begin
  dbms_wm.createWorkspace('PLAN_1_VARIANT_A');
end;
/
begin
  dbms_wm.createWorkspace('PLAN_1_VARIANT_B');
end;
/
So we can create a complete workspace hierarchy. Changes in one workspace are private and therefore visible only in this workspace. So we can change into the new workspace PLAN_1_VARIANT_A and do some additional changes.
begin
  dbms_wm.gotoWorkspace('PLAN_1_VARIANT_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 rows selected.
Now we have three versions of EMP in our database. One version (in the LIVE workspace) contains the original data (14 rows). The second version is contained in PLAN_1 and contains 10 rows. The third version in PLAN_1_VARIANT_A contains only 6 rows. Of course, the rows of all versions are stored in EMP_LT - the view EMP displays different information, depending on the current workspace. But at the next morning we decide that the changes to PLAN_1_VARIANT_A were nonsense - so we want to roll back these changes. For this we have the DBMS_WS.ROLLBACKWORKSPACE command.

4. Rollback and Merge

begin
  dbms_wm.rollbackWorkspace('PLAN_1_VARIANT_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 rows selected.
Taking the changes of a workspace to the parent workspace is being called a Merge operation. So if we want to have the state of workspace PLAN_1 as production, we need to merge that workspace to LIVE with DBMS_WM.MERGEWORKSPACE. A merge operation always goes from child to parent workspaces. And to root of the workspace hierarchy is LIVE. It's also possible to take changes in the parent workspace to a child workspace - but the Refresh operation will be covered in the next blog posting.
begin
  dbms_wm.mergeWorkspace('PLAN_1');
end;
/
Since the parent of PLAN_1 is LIVE, the changes will be public after this operation.
This concludes part one of my blog posting about Workspace Manager - part two will concentrate on further, important features.
  • How does a Refresh Operation work?
  • Assume a child Workspace is being merged to its parent. But in the parent there are also changes to the same table rows. How does Workspace Manager handle these conflicts?
  • Does Workspace Manager keep a history?
  • What is a Savepoint?
  • Is there are privilege model for Workspace Manager?
  • ...
Until then ... here's some material for further reading ...

Keine Kommentare:

Beliebte Postings