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 alDBMS_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. Eluse_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 defalse
. - 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;