Bonjour, je suis en train de mettre en place un systeme de file d'attente à l'aide des packages dbms_aqadm et dbms_aq.
J'ai donc créé une queue_table, avec une seule queue à l'interieur. Des utilisateurs peuvent envoyer des messages, ils sont alors placés dans une file d'attente, puis un autre utilisateur les recupere un à un. Jusque la, tout va bien.
Ma queue_table est bien mise à jour lors de l'envoi d'un message (on vois la date de l'envois, qui l'a envoyé, combien de temps le message reste dans la file d'attente, etc.), mais par contre elle n'est pas mise à jour lors de la reception d'un message (date de reception, nom du receptionneur ...).
De plus, les messages ne sont pas considérés comme lus, leur statut reste inchangé, et ils passent dans la table d'exception une fois que le temps arrive à expiration.
Pourtant, je les vois à la reception, ils sont tous receptionnés sans probleme, sans doublons, tout marche nickel.
J'arrive pas à comprendre d'où vient le problème, je me doute que ca vient des procédures de dequeue/enqueue mais à part ca...
Voici en gros les procédures que j'utilise:
Enqueue:
Dequeue:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 create or replace procedure enqueue_pharm(usermsg commande, urgence number) authid definer is enq_msgid raw(16); eot dbms_aq.enqueue_options_t; mpt dbms_aq.message_properties_t; envoyeur sys.aq$_agent; pragma autonomous_transaction; begin envoyeur := sys.aq$_agent(user, null, 0); mpt.priority := urgence; mpt.sender_id := envoyeur; if urgence < 5 then eot.sequence_deviation := dbms_aq.top; -- si le chiffre de l'urgence est < 5 else -- alors on le met au dessus de tous les eot.sequence_deviation := null; -- messages sinon, on le met a la suite end if; -- comme les autres if urgence < 10 then -- si l'urgence est < 10 on le place dans mpt.expiration := 60*5; -- l'exception au bout de 5 min else mpt.expiration := 1800; -- sinon c'est au bout de 30 min end if; dbms_aq.enqueue('aqadmin.commande_attente', eot, mpt, usermsg, enq_msgid); commit; end enqueue_pharm;
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 create or replace procedure dequeue_pharm(username_d varchar2) authid definer is deq_msgid raw(16); dot dbms_aq.dequeue_options_t; mpt dbms_aq.message_properties_t; payload_d commande; tmp pls_integer; pas_dispo exception; pragma autonomous_transaction; begin dot.consumer_name := username_d; dot.navigation := dbms_aq.first_message; dot.visibility := dbms_aq.immediate; dbms_aq.dequeue('aqadmin.commande_attente', dot, mpt, payload_d, deq_msgid); select quantite_i into tmp from inventaire where nom_i = payload_d.nom_c; if (tmp - payload_d.quantite_c) > 0 then update inventaire set quantite_i = quantite_i - payload_d.quantite_c where nom_i = payload_d.nom_c; else raise pas_dispo; end if; insert into sortie_prep (nom_s, quantite_s, dequeue_par, date_de_dequeue) values (payload_d.nom_c, payload_d.quantite_c, username_d, systimestamp); commit; exception when pas_dispo then dbms_output.put_line('il n y a pas ce qu il faut pour satisfaire la commande'); commit; end dequeue_pharm;
Et j'utilise deux autres petites procédures pour simplifier les choses:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 create or replace procedure mise_en_attente (quantite_m number, nom_m varchar2, priorite_m number) is usermsg aqadmin.commande; begin usermsg := aqadmin.commande(nom_m,quantite_m); enqueue_pharm(usermsg, priorite_m); end mise_en_attente;
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 create or replace procedure recuperer_messages authid definer is qlist dbms_aq.aq$_agent_list_t; agent_msg sys.aq$_agent; listen_timeout exception; pragma exception_init(listen_timeout, -25254); begin qlist(0) := sys.aq$_agent(user, 'aqadmin.commande_attente', null); -- loop begin dbms_aq.listen(agent_list => qlist, wait => 5, agent => agent_msg); if agent_msg.name = user then dequeue_pharm(user); end if; commit; end; --end loop; exception when listen_timeout then dbms_output.put_line('tous les messages de la file d attente ont été lus'); end recuperer_messages;
J'espere que c'est comprehensible, si vous avez besoin de précisions n'hesitez pas!
Merci d'avance, Crustyz
Partager