Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Pages: 1
Bonjour !
Je cherche à lancer une procédure stockée sur un serveur Oracle 10g depuis un appli PB 10.5.
Le hic est que cette procédure prends deux heures à finir et que pendant ce temps l'appli est bloquée.
J'aurais aimer savoir comment vous faites dans ce cas pour forcer l'appli à continuer sans attendre la fin du processus DB ?
Typiquement, ne pas attendre de return, travailler en asynchrone.
C'est un cas si classique que j'aurais penser que PB gérait ça facilement.
Or, je n'arrive pas à mettre la main sur un exemple correspondant.
J'ai tenté :
- une procédure sans return sur le serveur DB
- une fonction encapsulant l'appel à la fonction initiale sur le serveur DB
- une fonction allias en local external sur SQLCA
- la même en remote RPC
Sans succès...
J'en suis résigné à créer un Job Oracle sur la DB qui se chargera de lancer la procédure...
Puis l'encapsuler dans un package qui sera appelé par PB.
Un peu lourd quand même : il doit y avoir un autre moyen, non ???
Merci d'avance pour toute suggestion...
Bybye !
El Feliz
Win XP
PB 10.5
Oracle 10g
Dernière modification par elfeliz (02-12-2010 15:06:32)
Hors ligne
Bonjour, regarde du coté de la fonction Yield.
Hors ligne
Bonjour,
Il faut que tu lances ta procédure dans un thread différent. Pour cela, tu as à ta disposition les fonctions SharedObject.... (SharedObjectRegister, ...).
Il existe plusieurs exemples de mise en oeuvre sur codexchange (multithread).
Hors ligne
Un grand merci pour vos réponses !
je vais creuser ces directions et je reviens vers vous ;-)
Bybye,
El Feliz
Hors ligne
Bonjour,
Je reviens avec mon problème :-)
En fait, je pense que j'ai mal posé ma question.
En effet, mon but est de pouvoir lancer un process sur une DB ORACLE - quel qu'il soit : fonction, procédure, job, autre - sans que l'application ne reste en attente soit de la valeur de return, soit de la fin du process DB en question.
L'exemple classique, c'est de lancer un traitement lourd - genre calcul - sur la DB et puis de fermer l'appli PB qui l'aurait lancé (les erreurs et autres étant gérées par le DBMS).
D'après les tests que j'ai effectué, Yield ou le partage d'objet "sharés" ne résoud pas complétement mon problème :
Ces logiques permettent effectivement l'intervention sur un process en cours (yield ) ou l'ouverture d'autres fenêtres et objets PB pendant qu'un autre process tourne ( SharObject)... mais au sein de l'application initiale...
Ce qui fait que si je lance le process dans une fenêtre 1, je peux effectivement ouvrir une fenêtre 2, etc.
Mais je ne peux quitter l'application : le process ouvert en fenêtre 1 étant toujours en attente d'une réponse....
Peut-être qqchose m'a-t-il échappé ?
Ce qui m'étonne aussi c'est que sous ASE le problème ne se semble pas se poser.
Par exemple, j'ai testé une fonction en TL-SQL avec un wait , renvoyant un seul caractère, appelée par un client PB.
Dans ce cas, le client fait son job sans soucis du return : à savoir que si je mets le Wait en commentaire, il ramasse effectivement le caractère, mais que si je mets le wait à un délai de 2 sec., il continue sa route avec une valeur à null sans états d'âme et sans rester fixé sur l'attente d'une réponse.
C'est troublant et c'est peut-être une piste : où se cache la différence entre ASE et Oracle 10g sur ce point bien précis ????
Par ailleurs, j'ai également testé la propriété "Async" de l'objet de transaction, mais ça n'a rien changé...
J'ai l'impression de passer à côté d'un truc gros comme une maison ...
Avez-vous une idée ??
Merci d'avance,
Bybye
El Feliz
Hors ligne
Bonjour,
As-tu regardé du côté de $Universe sous Oracle?
Hors ligne
Pour un DW.retrieve en asynchrone il faut mettre une ligne commentée dans RetrieveRow (équivalent d'un Yield).
Sinon tu peux aussi lancer un job dans Oracle avec dbms_job.submit(...).
Hors ligne
Bonjour,
Quand tu essaye de le faire en utilisant les fonctions SharedObject.... (SharedObjectRegister, ...),
est-ce que tu as bien créer une nouvelle connection dans ton nouveau thread ?
Il me semble que ce soit nécessaire.
Par contre, je ne sais pas si il laissera fermer l'application ou pas.
Hors ligne
Je suis confronté à un problème similaire que celui de elfeliz
Pour ma part, j'ai une procédure stockée qui a traitement extrêmement long pour l'utilisateur.
Je met donc : SQLCA.dbParm = "Async = 1, DBGetTime = 2"
Mais lorsque j’exécute ma PS, pour l'exemple j'ai fait une petite procédure stockée qui attend un nombre de seconde passé en paramètre :DECLARE sp_wait PROCEDURE FOR Ma_Procédure_Stockée
@sec = 10
USING SQLCA;
EXECUTE sp_wait;
IF SQLCA.sqlcode < 0 THEN
MessageBox(gAppNom, "Erreur lors de la génération du fichier routeur !~r" + SQLCA.Sqlerrtext, StopSign!, Ok!)
Return -1
END IF
CLOSE sp_wait;
Mais je n'arrive pas à récupérer la main avant la fin du traitement de la PS.
Je ne crois pas que dans le cas de @elfeliz ni du miens le Yield() correspond au problème.
En utilisant les "SharedObject", le programme va quand même se bloqué en attendant la fin du traitement, il me semble
Je suis donc aussi coincé
Hors ligne
salut
vous avez essaye les job oracle ?
Hors ligne
Pour ma part je suis sur SQL Server, et si on lance une tache, l'appli est bloqué le temps du traitement de cette tache...
Hors ligne
JCZ a écrit:
vous avez essaye les job oracle ?
erasorz a écrit:
Sinon tu peux aussi lancer un job dans Oracle avec dbms_job.submit(...).
Hors ligne
Bonjour,
En utilisant les "SharedObject", le programme va quand même se bloqué en attendant la fin du traitement, il me semble
Non, uniquement le thread que tu as lancé. Tu peux continuer à travailler avec le programme normalement.
Mais, si à l'issue de l'exécution de la procédure stockée, vous ne procédez pas à une quelconque exploitation des résultats/données de la procédure, un job devait suffire ou votre programme doit procéder à un traitement à l'issue de l'exécution de la procédure ?
Hors ligne
Bonjour Tout le monde !
Merci pour vos réponses.
En résumé :
- Je cherche à lancer un traitement long sur une db. Je voudrais que l'utilisateur puisse lancer le traitement, fermer l'appli, son pc et rentrer chez lui pendant que ça tourne en DB :-)
- C'est sur Oracle, avec un client PB, deux tiers.
Les essais :
- Yield et sharedobjects me laissent le problème de ne pas pouvoir fermer l'application (ok, on peut passer à un autre écran, lancer d'autres process, etc. mais l'appli reste toujours en attente sur un objet... certes "parallèle", mais bloquant la fermeture).
- L'option Async = 1 ne m'a pas donné de modification de comportement.
Solution adoptée :
- Une procédure Oracle en charge de créer un job --> utilise DBMS_SCHEDULER.CREATE_JOB ()
- Le job en question est chargé de lancer la fonction Oracle initialement demandée.
- J'appelle la procédure de création de job via mon application cliente PB : la création réussit et mon appli peut fermer.
- De son côté la fonction de calcul démarre et poursuit son job sur le serveur DB... à l'heure précisée dans le scheduler.
Conclusion :
C'est lourd mais ça marche
Remarque :
Le problème ne s'était pas posé sur des essais PB -> ASE : comportement asynchrone sans paramétrages particulier.
Aussi, j'étais convaincu qu'il y avait moyen avec Oracle aussi, mais là, je sèche ...
Merci à tous,
Et si qqun a une solution sans passer par les jobs Oracle, je suis toujours preneur !!!!
Bybye,
El Feliz
Hors ligne
Pages: 1