Oracle
 sql >> Base de données >  >> RDS >> Oracle

Paralléliser les appels en PL/SQL

Vous pouvez utiliser le dbms_job (ou dbms_scheduler ) pour soumettre des travaux qui s'exécuteront en parallèle. Si vous utilisez dbms_job , la soumission des travaux fera partie de la transaction afin que les travaux démarrent une fois la transaction terminée.

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;

Si vous utilisez dbms_scheduler , la création d'une nouvelle tâche n'est pas transactionnelle (c'est-à-dire qu'il y aurait des validations implicites chaque fois que vous créez une nouvelle tâche), ce qui peut entraîner des problèmes d'intégrité transactionnelle si d'autres tâches sont effectuées dans la transaction où cette procédure est appelée. D'autre part, si vous utilisez dbms_scheduler , il peut être plus facile de créer les travaux à l'avance et de les exécuter simplement à partir de la procédure (ou d'utiliser dbms_scheduler pour créer une chaîne qui exécute le travail en réponse à une autre action ou un événement tel que mettre un message dans une file d'attente).

Bien sûr, avec l'une ou l'autre solution, vous devrez ensuite créer l'infrastructure pour surveiller la progression de ces trois tâches en supposant que vous vous souciez de savoir quand et si elles réussissent (et si elles génèrent des erreurs).

Si vous comptez utiliser DBMS_SCHEDULER

  • Il n'est pas nécessaire d'utiliser SQL dynamique. Vous pouvez abandonner le EXECUTE IMMEDIATE et appelez simplement le DBMS_SCHEDULER les procédures du package directement comme vous le feriez pour n'importe quelle autre procédure.
  • Lorsque vous appelez RUN_JOB , vous devez passer un deuxième paramètre. Le use_current_session Le paramètre contrôle si le travail s'exécute dans la session en cours (et bloque) ou s'il s'exécute dans une session distincte (auquel cas la session en cours peut continuer et faire d'autres choses). Étant donné que vous souhaitez exécuter plusieurs tâches en parallèle, vous devez transmettre une valeur de false .
  • Bien que ce ne soit pas obligatoire, il serait plus conventionnel de créer les jobs une seule fois (avec auto_drop défini sur false) puis exécutez-les simplement à partir de votre procédure.

Donc, vous voudriez probablement créer les travaux en dehors du package, puis votre procédure deviendrait simplement

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;