2009-02-23 25 views
23

¿Hay alguna función de llamada asincrónica en PL/SQL? Supongamos que estoy en un bloque de código, me gustaría llamar a un procedimiento varias veces y no me molestaría cuándo y qué devuelve el procedimiento.¿Podemos usar el enhebrado en PL/SQL?

BEGIN 
    myProc(1,100); 
    myProc(101,200); 
    myProc(201,300); 
    ... 
    ... 

END; 

En el caso anterior, yo no quiero que mi código para esperar a que myProc (1100) para terminar el procesamiento antes de ejecutar (101.200)
Gracias.

Respuesta

23

1 de enfoques DBMS_SCHEDULER y DBMS_JOB, sino también considerar si usted debe estar usando un enfoque diferente.

Si tiene un procedimiento que se ejecuta en modo fila por fila y encuentra que es lento, la respuesta probablemente no sea ejecutar el procedimiento varias veces de manera simultánea sino para garantizar que se utiliza un enfoque basado en conjunto en lugar. En un extremo, incluso puede usar consulta paralela y DML paralelo para reducir el tiempo del reloj de pared del proceso.

Menciono esto solo porque es una falla muy común.

+3

Una vez que deja la sugerencia paralela fuera del laboratorio, cada programador de Tom, Dick y Harry lo colocará en cada consulta como si fuera un parámetro . ser vewy, vewy cawfule. –

+0

Sí, hará que las consultas en los cerdos de recursos en un sistema ocupado. En algo así como un almacén de datos, es bastante relevante para el código ETL o los informes. Usarlo sin una maldita buena razón en un sistema transaccional ocupado o en un informe operacional sobre dicho sistema debería ser motivo para una paliza severa. – ConcernedOfTunbridgeWells

17

enviarlo en un DBMS_JOB así:

declare 
    ln_dummy number; 
begin 
    DBMS_JOB.SUBMIT(ln_dummy, 'begin myProc(1,100); end;'); 
    DBMS_JOB.SUBMIT(ln_dummy, 'begin myProc(101,200); end;'); 
    DBMS_JOB.SUBMIT(ln_dummy, 'begin myProc(201,300); end;'); 
    COMMIT; 
end; 

que necesitará el parámetro job_queue_processes las posiciones> 0 para desovar hilos para procesar los puestos de trabajo. Puede consultar los trabajos examinando la vista user_jobs.

Tenga en cuenta que esto se aplica a Oracle 9i, no estoy seguro de qué soporte tiene 10g. Ver más información here.

EDIT: Agregado perdió COMMIT

+2

Para obtener información, DBMS_JOB quedó obsoleto en Oracle 10g por DBMS_SCHEDULER. Consulte http://download.oracle.com/docs/cd/B12037_01/server.101/b10739/jobtosched.htm –

+0

Un truco con esto es que debe COMPROMETERSE antes de que los trabajos realmente comiencen a ejecutarse. He visto esto perdido por algunas personas. –

5

Otra forma de hacerlo en paralelo (multi-threaded) se muestra PL/SQL aquí:

http://www.williamrobertson.net/documents/parallel-plsql-launcher.html

La desventaja de usar DBMS_JOB o dbms_schedular es que no se sabe muy bien cuando tus tareas hayan terminado Leí que no te molestas, pero tal vez cambies de opinión en el futuro.

EDIT:

En este artículo se describe http://www.devx.com/dbzone/10MinuteSolution/20902/0/page/1 otra manera. Utiliza dbms_job y dbms_alert. Las alertas se utilizan para indicar que los trabajos están terminados (señal de devolución de llamada).

+1

Con DBMS_Scheduler puede envolver fácilmente la llamada para ejecutar una cadena de programador en un procedimiento que verificará la finalización de los pasos de la cadena y volverá al procedimiento de llamada al completarse o fallar la cadena. –

-1

¿Ha considerado utilizar Oracle Advaned Queuing?

9

para el procesamiento paralelo PL/SQL tiene las siguientes opciones:

Estos le permitirá "emular" se bifurcan y con hilo en PL/SQL. Por supuesto, al utilizar estos, puede darse cuenta de la necesidad de comunicarse entre los procedimientos ejecutados en paralelo. Para hacerlo echa un vistazo a:

Personalmente he implementado un sistema de procesamiento paralelo usando DBMS_SCHEDULER, y se utiliza para la comunicación entre DBMS_PIPE "hilos". ¡Estaba muy contento con la combinación de los dos, y mi objetivo principal (reducir los tiempos de procesamiento principales con un procedimiento particular de gran peso) se logró!

1

El enfoque de canalización paralela enumerado aquí por askTom proporciona un enfoque más complejo, pero en realidad se detendrá hasta que el trabajo esté completo, a diferencia de las técnicas de trabajo DBMS. Dicho esto, hizo pregunta por la técnica "asíncrona", y DBMS_JOB es perfecto para eso.

5

Tiene otra opción que comienza en 11g. Oracle ha presentado un paquete que hace algo similar a lo que quiere hacer, llamado DBMS_PARALLEL_EXECUTE

Según ellos, "El paquete DBMS_PARALLEL_EXECUTE permite al usuario actualizar incrementalmente los datos de la tabla en paralelo". Un buen resumen de cómo usarlo es here

Básicamente, usted define una forma que Oracle debería utilizar para dividir su trabajo en pedazos (en su caso, parece que está pasando algo de valor clave), y luego comenzará cada una de las piezas individualmente. Sin duda hay un poco de planificación y un poco de codificación adicional para poder usarlo, pero nada que no debas haber estado haciendo de todos modos.

La ventaja de usar un método sancionado como este es que Oracle incluso proporciona vistas de bases de datos que se pueden usar para monitorear cada uno de los hilos independientes.