Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Parallelisieren von Aufrufen in PL/SQL

Sie können den dbms_job verwenden (oder dbms_scheduler )-Paket zum Übermitteln von Jobs, die parallel ausgeführt werden. Wenn Sie dbms_job verwenden , ist das Senden der Jobs Teil der Transaktion, sodass die Jobs gestartet werden, sobald die Transaktion abgeschlossen ist.

CREATE PACKAGE BODY pkg IS
    CREATE PROCEDURE do
    IS
      l_jobno pls_integer;
    BEGIN
        dbms_job.submit(l_jobno, 'begin other_pkg.other_proc; end;' );
        dbms_job.submit(l_jobno, 'begin other_pkg2.other_proc2; end;' );
        dbms_job.submit(l_jobno, 'begin other_pkg3.other_proc3; end;' );
    END;
END;

Wenn Sie dbms_scheduler verwenden , ist das Erstellen eines neuen Jobs nicht transaktional (d. h. jedes Mal, wenn Sie einen neuen Job erstellen, würden implizite Festschreibungen erfolgen), was zu Problemen mit der Transaktionsintegrität führen kann, wenn in der Transaktion, in der diese Prozedur aufgerufen wird, andere Arbeiten ausgeführt werden. Andererseits, wenn Sie dbms_scheduler verwenden , kann es einfacher sein, die Jobs im Voraus zu erstellen und sie einfach über die Prozedur auszuführen (oder dbms_scheduler zu verwenden um eine Kette zu erstellen, die den Job als Reaktion auf eine andere Aktion oder ein Ereignis ausführt, z. B. das Einreihen einer Nachricht in eine Warteschlange).

Natürlich müssten Sie bei beiden Lösungen dann die Infrastruktur aufbauen, um den Fortschritt dieser drei Jobs zu überwachen, vorausgesetzt, dass es Sie interessiert, wann und ob sie erfolgreich sind (und ob sie Fehler erzeugen).

Wenn Sie DBMS_SCHEDULER verwenden werden

  • Es besteht keine Notwendigkeit, dynamisches SQL zu verwenden. Sie können EXECUTE IMMEDIATE weglassen und rufen Sie einfach den DBMS_SCHEDULER auf die Prozeduren des Pakets direkt, so wie Sie es mit jeder anderen Prozedur tun würden.
  • Wenn Sie RUN_JOB aufrufen , müssen Sie einen zweiten Parameter übergeben. Die use_current_session Der Parameter steuert, ob der Job in der aktuellen Sitzung ausgeführt wird (und blockiert) oder ob er in einer separaten Sitzung ausgeführt wird (in diesem Fall kann die aktuelle Sitzung fortgesetzt und andere Dinge ausgeführt werden). Da Sie mehrere Jobs parallel ausführen möchten, müssen Sie den Wert false übergeben .
  • Obwohl es nicht erforderlich ist, wäre es konventioneller, die Jobs einmal zu erstellen (mit auto_drop auf "false" setzen) und sie dann einfach von Ihrer Prozedur aus ausführen.

Sie würden also wahrscheinlich die Jobs außerhalb des Pakets erstellen wollen und dann würde Ihre Prozedur einfach zu

werden
CREATE PACKAGE BODY pkg IS
    CREATE PROCEDURE do
    IS
    BEGIN
        DBMS_SCHEDULER.RUN_JOB('job_other_pkg.other_proc', false);
        DBMS_SCHEDULER.RUN_JOB('job_other_pkg2.other_proc2', false);
        DBMS_SCHEDULER.RUN_JOB('job_other_pkg3.other_proc3', false);
    END;
END;