1つのアプローチは、OracleのAdvancedQueuingを使用することです。そのためには、キュー(およびキュー表)を設定し、キュー内の次のメッセージを待機するPL/SQLプロシージャを作成する必要があります。
次に、C++側はPL/ SQLプロシージャを呼び出します。このプロシージャは、次のイベントが発生したときに戻ります。
Oracle側では、DBMS_SCHEDULERまたは同様の機能を使用してイベントを作成する必要があります。つまり、適切なタイミングで新しいメッセージをキューに挿入する必要があります。
それはまだポーリングアプローチです。ただし、2つのイベントの間にアクティビティはまったくありません。
アップデート:
ここにいくつかのサンプルコードがあります。
キューの初期設定(メッセージには数値とテキスト値が含まれています):
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;
/
パッケージヘッダー:
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;
/
パッケージ本体:
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;
/
データベースサーバーは、次のコードを使用してメッセージを送信できます。
sample_queue_pkg.put_msg('run_task', 8234);
commit;
C ++サーバーは、保存されたを呼び出すメッセージを待機(および受信)できますsample_queue_pkg.get_next_msg
。このパラメーターi_max_wait
は、次のメッセージを待機する最大時間を秒単位で指定します。次のメッセージを待機し、サーバーが終了しようとしているというシグナルを受信するまでメッセージを処理するループを実装することをお勧めします。