sql >> Databasteknik >  >> RDS >> Oracle

Parallellerande samtal i PL/SQL

Du kan använda dbms_job (eller dbms_scheduler )-paket för att skicka in jobb som kommer att köras parallellt. Om du använder dbms_job , kommer att skicka in jobben att vara en del av transaktionen så jobben startar när transaktionen är klar.

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;

Om du använder dbms_scheduler , att skapa ett nytt jobb är inte transaktionellt (dvs. det skulle finnas implicita commits varje gång du skapade ett nytt jobb) vilket kan orsaka problem med transaktionsintegriteten om det finns annat arbete som görs i transaktionen där denna procedur anropas. Å andra sidan, om du använder dbms_scheduler , kan det vara lättare att skapa jobben i förväg och helt enkelt köra dem från proceduren (eller att använda dbms_scheduler för att skapa en kedja som kör jobbet som svar på någon annan åtgärd eller händelse som att lägga ett meddelande i en kö).

Naturligtvis, med båda lösningarna, måste du sedan bygga infrastrukturen för att övervaka framstegen för dessa tre jobb, förutsatt att du bryr dig om när och om de lyckas (och om de genererar fel).

Om du ska använda DBMS_SCHEDULER

  • Det finns inget behov av att använda dynamisk SQL. Du kan ta bort EXECUTE IMMEDIATE och ring bara DBMS_SCHEDULER paketets procedurer direkt precis som du skulle göra med vilken annan procedur som helst.
  • När du ringer RUN_JOB måste du skicka in en andra parameter. use_current_session parametern styr om jobbet körs i den aktuella sessionen (och blockerar) eller om det körs i en separat session (i vilket fall den aktuella sessionen kan fortsätta och göra andra saker). Eftersom du vill köra flera jobb parallellt måste du skicka in värdet false .
  • Även om det inte krävs, skulle det vara mer vanligt att skapa jobben en gång (med auto_drop inställd på false) och kör dem sedan från din procedur.

Så du skulle förmodligen vilja skapa jobben utanför paketet och då skulle din procedur bara bli

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;


  1. Vad orsakar Mer känns inte igen... fel när Postgresql 11 körs på en Windows-maskin?

  2. Hur återställs när ett fel uppstår när SQL loader-kommandot körs?

  3. Hur tar man bort mysql-raden efter tiden?

  4. Använda Oracle JDeveloper 12c med Oracle Database 12c på Oracle Cloud Platform, del 2