Ein Ansatz ist die Verwendung von Oracle's Advanced Queuing . Zu diesem Zweck müssen Sie eine Warteschlange (und eine Warteschlangentabelle) einrichten und eine PL/SQL-Prozedur schreiben, die auf die nächste Nachricht in der Warteschlange wartet.
Die C++-Seite ruft dann die PL/SQL-Prozedur auf, die zurückkehrt, wenn das nächste Ereignis aufgetreten ist.
Auf der Oracle-Seite müssen Sie DBMS_SCHEDULER oder eine ähnliche Einrichtung zum Erstellen des Ereignisses , d. h. zum richtigen Zeitpunkt eine neue Nachricht in die Warteschlange einzufügen.
Es ist immer noch ein Umfrageansatz. Es gibt jedoch absolut keine Aktivität zwischen zwei Ereignissen.
Aktualisierung:
Hier ist ein Beispielcode.
Initiale Einrichtung der Warteschlange (die Nachricht enthält einen numerischen und einen Textwert):
grant AQ_ADMINISTRATOR_ROLE to appuser;
grant EXECUTE ON DBMS_AQ to appuser;
grant EXECUTE ON DBMS_AQ to appuser;
CREATE TYPE sample_payload_type AS OBJECT
(
cmd VARCHAR2(20),
id NUMBER
);
BEGIN
DBMS_AQADM.CREATE_QUEUE_TABLE (
queue_table => 'sample_queue_table',
queue_payload_type => 'sample_payload_type',
sort_list => 'ENQ_TIME',
compatible => '10.0'
);
END;
/
BEGIN
DBMS_AQADM.CREATE_QUEUE (
queue_name => 'sample_queue',
queue_table => 'sample_queue_table'
);
DBMS_AQADM.START_QUEUE (
queue_name => 'sample_queue'
);
END;
/
Paketkopf:
create or replace package sample_queue_pkg
as
procedure get_next_msg(
i_max_wait number
,o_cmd out varchar2
,o_id out number
);
procedure put_msg(
i_cmd varchar2
,i_id number
);
end sample_queue_pkg;
/
Pakettext:
create or replace package body sample_queue_pkg
as
procedure get_next_msg(
i_max_wait number
,o_cmd out varchar2
,o_id out number
)
is
dequeue_options dbms_aq.dequeue_options_t;
message_properties dbms_aq.message_properties_t;
message_handle RAW(16);
message sample_payload_type;
NO_MESSAGE_RECEIVED EXCEPTION;
PRAGMA EXCEPTION_INIT(NO_MESSAGE_RECEIVED, -25228);
begin
dequeue_options.wait := i_max_wait;
DBMS_AQ.DEQUEUE (
queue_name => 'appuser.sample_queue',
dequeue_options => dequeue_options,
message_properties => message_properties,
payload => message,
msgid => message_handle
);
o_cmd := message.cmd;
o_id := message.id;
exception
when NO_MESSAGE_RECEIVED then
o_cmd := null;
o_id := null;
end get_next_msg;
procedure put_msg(
i_cmd varchar2
,i_id number
)
is
enqueue_options dbms_aq.enqueue_options_t;
message_properties dbms_aq.message_properties_t;
message_handle RAW(16);
message sample_payload_type;
message_id NUMBER;
begin
message := sample_payload_type(i_cmd, i_id);
DBMS_AQ.ENQUEUE(
queue_name => 'appuser.sample_queue',
enqueue_options => enqueue_options,
message_properties => message_properties,
payload => message,
msgid => message_handle
);
end put_msg;
end sample_queue_pkg;
/
Der Datenbankserver kann eine Nachricht mit folgendem Code senden:
sample_queue_pkg.put_msg('run_task', 8234);
commit;
Der C++-Server kann auf Nachrichten warten (und sie empfangen), indem er die gespeicherte sample_queue_pkg.get_next_msg
aufruft . Der Parameter i_max_wait
gibt die maximale Wartezeit in Sekunden auf die nächste Nachricht an. Wahrscheinlich möchten Sie eine Schleife implementieren, die auf die nächste Nachricht wartet und sie verarbeitet, bis sie ein Signal erhält, dass der Server dabei ist, sich zu beenden.