sql >> Base de Datos >  >> RDS >> Oracle

Paralelizar llamadas en PL/SQL

Puede usar el dbms_job (o dbms_scheduler ) para enviar trabajos que se ejecutarán en paralelo. Si está utilizando dbms_job , enviar los trabajos será parte de la transacción, por lo que los trabajos comenzarán una vez que se complete la transacción.

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 está utilizando dbms_scheduler , la creación de un nuevo trabajo no es transaccional (es decir, habría compromisos implícitos cada vez que crea un nuevo trabajo), lo que puede causar problemas con la integridad transaccional si se está realizando otro trabajo en la transacción en la que se llama a este procedimiento. Por otro lado, si está utilizando dbms_scheduler , puede ser más fácil crear los trabajos por adelantado y simplemente ejecutarlos desde el procedimiento (o usar dbms_scheduler para crear una cadena que ejecute el trabajo en respuesta a alguna otra acción o evento, como poner un mensaje en una cola).

Por supuesto, con cualquiera de las dos soluciones, necesitará construir la infraestructura para monitorear el progreso de estos tres trabajos, suponiendo que le importe cuándo y si tienen éxito (y si generan errores).

Si va a utilizar DBMS_SCHEDULER

  • No es necesario utilizar SQL dinámico. Puedes deshacerte del EXECUTE IMMEDIATE y simplemente llame al DBMS_SCHEDULER los procedimientos del paquete directamente como lo haría con cualquier otro procedimiento.
  • Cuando llamas a RUN_JOB , debe pasar un segundo parámetro. El use_current_session El parámetro controla si el trabajo se ejecuta en la sesión actual (y se bloquea) o si se ejecuta en una sesión separada (en cuyo caso la sesión actual puede continuar y hacer otras cosas). Dado que desea ejecutar varios trabajos en paralelo, deberá pasar un valor de false .
  • Aunque no es obligatorio, sería más convencional crear los trabajos una vez (con auto_drop establecido en falso) y luego ejecútelos desde su procedimiento.

Por lo tanto, probablemente desee crear los trabajos fuera del paquete y luego su procedimiento se convertiría en

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;