ルール・アプリケーションは複数層モードで実行できます。複数層にまたがるルール・アプリケーションで、ルール管理はデータベースで処理されるが、ルールのアクション実行はアプリケーション・サーバーで処理される場合、イベント と一致するルールのアクションは、アクション・コールバック・プロシージャから起動できません。かわりに、結果ビューは、外部アクション実行に使用できるイベントと一致ルールに関する情報を使用して移入されます。結果ビューを問い合せると、イベントと一致するルールを判別でき、それに対応するアクションを実行できます。
アプリケーション・サーバーでアクション実行が発生する特定のルールを備えたルール・アプリケーションを処理するには、アクション・コールバック・プロシージャを構成する以外に、外部実行用のルール・クラスも構成する必要があります。この構成手順は第2.3項で説明した手順と類似していますが、次のように変更されています。
データベースにオブジェクト型としてイベント構造を作成します(第2.3項の手順1と同様)。
TravelPromotion
ルール・クラスを作成します。さらに、結果ビューを定義します(当初は使用しない場合でも定義します)。結果ビューは、たとえば、TravelPromotionルール・クラスの作成に使用できます。その場合、ルール・クラスのいくつかのイベントを処理する各ルール・セッションでは、実行時にアクション実行をアクション・コールバック・プロシージャ(dbms_rlmgr.process_rules( )
のコール、第2.3項の手順5を参照)または外部アクション実行(dbms_rlmgr.add_event( )
のコール、この項の手順5を参照)のいずれかに切り替えることができます。このために、ルール・クラスは、次の例に示すように、アクション・コールバック・プロシージャと結果ビューを使用して構成します。
BEGIN
dbms_rlmgr.create_rule_class (
rule_class => 'TravelPromotion',
event_struct => 'AddFlight',
action_cbk => 'PromoAction',
rslt_viewnm => 'MatchingPromos',
actprf_spec => 'PromoType VARCHAR2(20),
OfferedBy VARCHAR2(20)');
END;
このコマンドによって、次のMatchingPromos
結果ビューが作成され、ルール評価の結果が保持されます。この結果ビューには、システム生成のイベント識別子(rlm$eventid
)、イベント・インスタンス(rlm$event
、単純なプリミティブ・イベントの場合)、一致ルールのルール識別子(rlm$ruleid
)、ルール条件(rlm$rulecond
)およびルールの説明(rlm$ruledesc
)がリストされた一連の固定列と、ルールに関連付けられたアクション・プリファレンスを表す一連の可変列(この例ではPromoType
列とOfferedBy
列)があります。イベントがルール・クラス内の一連のルールと一致する場合は、このビューを問い合せることで、そのイベントおよび一致したルールに関する情報を取得できます。
VIEW MatchingPromos ( rlm$eventid ROWID, rlm$event AddFlight, rlm$ruleid VARCHAR2(100), PromoType VARCHAR2(20), OfferedBy VARCHAR2(20)), rlm$rulecond VARCHAR2(4000), rlm$ruledesc VARCHAR2(1000, rlm$enabled CHAR(1) DEFAULT 'Y'); );
コンポジット・イベントに対して構成したルール・クラスの場合、結果ビューは、1つ以上のプリミティブ・イベントを使用してルールを評価した結果を保持するように構成されます。このために、このビューは、コンポジット・イベント内のプリミティブ・イベントごとに個別の列を持つように作成されます。たとえば、第2.4.1項で定義したルール・クラスの結果ビューは、次のように作成されます。
VIEW CompMatchingPromos ( rlm$eventid ROWID, Flt AddFlight, Car AddRentalCar, rlm$ruleid VARCHAR2(100), PromoType VARCHAR2(20), OfferedBy VARCHAR2(20), rlm$rulecond VARCHAR2(4000), rlm$ruledesc VARCHAR2(1000) rlm$enabled CHAR(1) DEFAULT 'Y');
アクション・コールバック・プロシージャを実装します(第2.3項の手順3と同様)。
ルール・クラスにルールを追加します(第2.3項の手順4と同様)。
イベントに対する一致ルールを識別します。この手順では、一致ルールを識別して対応するアクションを実行する処理ルール・プロシージャ(dbms_rlmgr.process_rules( )
)のかわりに、追加イベント・プロシージャ(dbms_rlmgr.add_event( )
)を使用します。このプロシージャでは、イベントを一度に1つずつルール・クラスに追加し、指定のイベントに対する一致ルールを識別します。この一致ルールには、後でMatchingPromos
結果ビューを使用してアクセスできます。
BEGIN
dbms_rlmgr.add_event (
rule_class => 'TravelPromotion',
event_inst => AddFlight.getVarchar(987, 'Abcair', 'Boston', 'Orlando', '01-APR-2003', '08-APR-2003')
);
END;
結果ビューを問い合せて一致ルールを検索します。たとえば、次の問合せでは、現行のセッションで追加されたすべてのイベントと、対応する一致ルール(およびそのアクション・プリファレンス)のリストが戻されます。
SELECT rlm$eventid, rlm$ruleid, PromoType, OfferedBy FROM MatchingPromos;
この問合せの結果を使用すると、アプリケーション・サーバーで適切なアクションを実行できます。単一のイベント構造に対して定義されたルール・クラスの場合、このビューには、システム生成のイベント識別子を戻すrlm$eventid
列と、実際のイベントを(プリミティブ・イベント構造の)オブジェクト・インスタンスとして戻すrlm$event
列が暗黙的に設定されます。
結果セットから1つの候補ルールを識別する必要がある場合は(競合解消)、ORDER BY
、GROUP BY
およびHAVING
句を使用できます。アクション実行用のコールバック・メカニズムで競合解消のために使用できるのは、ORDER BY
セマンティクスのみです。詳細は、第3.2項を参照してください。たとえば、トラベル・サービスのアプリケーションでタイプごとに1つの販促のみを提供する場合は、次の分析問合せを使用して、起動する適切なルールを識別できます。
SELECT rlm$eventid, rlm$ruleid, PromoType, OfferedBy FROM (SELECT rlm$eventid, rlm$ruleid, PromoType, OfferedBy, ROW_NUMBER( ) over (PARTITION BY PromoType ORDER BY rlm$ruleid) rnum FROM MatchingPromos) WHERE rnum=1;
この例では、起動対象として識別されたルールは、TRUEと評価された一連のルールに対する結果セットの問合せで最初に戻されたルール(rnum=1
)です。このルールは、販促のタイプ別にパーティション化され、rlm$ruleid
列の値に従って昇順に並べられます。
ルール評価の結果は、ルール・セッションの終了まで使用可能です。デフォルトでは、データベース・セッション(接続から切断まで)がルール・セッションとみなされます。または、セッションの再設定プロシージャ(dbms_rlmgr.reset_session( )
)を使用すると、データベース・セッション内でルール・セッションを終了し、新規セッションを開始できます。ルール・セッションの開始時には、結果ビューは空であることに注意してください。
ルール実行で使用されるイベントを使用します。イベントに対して使用率ポリシーを指定すると、そのイベントにルールの排他実行または共有実行のマーク付けができます。第2.3項で、イベントを排他的に使用するようにTravelPromotionルール・クラスが構成されていた場合、ルールの実行で使用したイベントは、システムから即時に削除され、他の(一致)ルールでは使用できなくなります。アクション・コールバック・プロシージャが使用されるため、ルール・マネージャは排他イベントの使用を自動的に処理します。ただし、外部アクション実行が使用される場合、アプリケーションでは、イベント使用プロシージャ(dbms_rlmgr.consume_event( )
)を使用して、アクション実行用に選択したイベントを明示的に使用する必要があります。このプロシージャによって、複数の同時セッションが同じイベントを使用しようとした場合は、1つのセッションのみの正常終了が保証されます。したがって、イベントが正常に使用された場合は、次のように特定のルールに対するアクションが実行されます。
DECLARE consumed number; BEGIN consumed := dbms_rlmgr.consume_event ( rule_class => 'TravelPromotion', event_ident => :eventIdBind); IF (consumed = 1) THEN OfferPromotion(…); -- offer the promotion only if the event -- consumption is successful END IF; END;
イベント識別子は、MatchingPromos
結果ビューのrlm$eventid
列にリストされた値から取得されます。すべてのイベントで使用率ポリシー(第3.2項を参照)を共有する場合、CONSUME_EVENT
コールは常に1を戻し、イベントは使用可能のままです。排他使用として構成されているイベントのみが使用され、対応する行が結果ビューから削除されることに注意してください。
ルール・マネージャを使用して設計されたルールベースのアプリケーションは、操作のモードに応じてステップの数が異なります。単一層または複数層のいずれの場合も、ほとんどすべてのステップは一度に実装されます。実装した後は、エンドユーザーがルール・マネージャAPIを扱う必要はありません。新規ルールは、ルール・クラス表に対してSQL INSERT
を使用して追加され、より大きいアプリケーションに埋め込まれているランタイム・コールによって自動的に処理されます。?
データベースに格納されたルール・クラスは、次のいずれかのモードで操作できます。
単一層モード: ルール評価、候補ルールまたは実行するアクションの識別、アクションの実行、およびイベントの使用(オプション)が、すべて単一のPROCESS_RULES
コール(イベント・インスタンスで渡されます)を使用してデータベース内で実行されます。これは、データベース外で実行されているアプリケーションの場合も含めて、最も一般的なモードです。
複数層モード: 前述の単一層モードで実行されるステップの内、ルール評価はデータベース内で実行され、残りのステップは適切なデータベース・コールを使用していずれかの層で実行できます(第6.2.2項の説明にあるように、ステップは最大4つです)。
ルール・アプリケーションを複数層モードで操作する主な理由は、次のとおりです。
ルールによって提案されたアクションは、データベース関数またはパッケージ(PL/SQLかJava)としてデータベース内に実装できないため。
ルール・クラスの競合解消基準は複雑で、SQL ORDER BY
句を使用して指定できないため。ルール・セットを処理する単一イベントで複数のルールが一致する場合は、ルールのサブセットの識別、起動するルールの正確な順序の判別(あるいはその両方)に、競合解消基準が使用されます。通常、ほとんどのアプリケーションでは単純なSQL ORDER BY
句で十分です。ただし、複数層モードでは、競合解消基準に対して任意のSQL演算子(分析演算子を含む)を使用できます。
ルール・マネージャを複数層モードで使用する4つのステップは、次のとおりです。
dbms_rlmgr.add_event
プロシージャをコールして、イベントの情報をデータベースに提供します。
適用するルールをデータベースに問い合せます(SQL ORDER BY
句を伴う複雑な問合せを使用したビューの問合せなど)。
アプリケーションの競合解消基準に基づいて、起動する一致ルールのサブセットを識別し、dbms_rlmgr.consume_event
関数コールを使用してイベントを使用し、アクションの実行の準備をします。
ステップ3が正常に終了した後は、プログラマが定義済のアクションにマップするルーチン(ローカル、中間層にあります)をコールします。
複数層モードを使用する唯一の理由が、アプリケーション・サーバーでのアクション実行にある場合は、いくつかの変更を加えて単一層モードを使用できます(これによって、ステップ数が2に減ります)。単一層モードでアクション・コールバック・プロシージャを実装してアクションをエンキューし、残りの操作(使用)を継続します。アプリケーション・サーバーでは、このアクション・キューをサブスクライブしてアクションを実行できます。この構成で必要なのは、最小数の2つのデータベース・コール(PROCESS_RULES
コールとDEQUEUE
コール)です。
ルール・マネージャは、データベース機能として、マルチユーザーと同時セッションの環境で使用できます。ルール・マネージャを使用すると、2つの同時セッションで同じルール・セットを処理し、ルールと一致した共通イベントの削除を要求できます。この場合は、いずれか1つのセッションのみ成功します。ルール・アプリケーションが単一層モードで稼働している場合、この処理は、イベント・タイプに対してEXCLUSIVE
使用率ポリシーを指定して実行します。PROCESS_RULE
プロシージャはイベント使用ロジックを制御し、セッション間のデッドロックを防止します。ルール・アプリケーションが複数層モードで稼働している場合、中間層アプリケーションはCONSUME_EVENT
関数をコールして、ルールのアクションを実行することを示す必要があります(ユーザー・アプリケーションは競合解消基準を制御しているため)。アクションで必要なイベントの1つが別の同時セッションですでに使用されている場合、このコールは0(ゼロ)を戻します。したがって、アプリケーションでは、このコールが1を戻した場合のみアクションを実行する必要があります。すべてのイベントがSHARED
使用(複数のルール実行に対してイベントが共有されることを意味します)に構成されている場合は、このステップをスキップできることに注意してください。
複数層モードを使用する主な理由の1つは、複雑な競合解消基準を実装することであるため、イベントをルールと一致させた結果はリレーションとして(アプリケーションに)公開され、複合SQLを使用して問い合せることができます。また、このビューを使用すると、外部要素に基づいて異なる競合解消基準を指定できます(たとえば、ある競合解消基準は午前9時〜午後5時に使用し、それ以外の時間は別の基準を使用します)。
ルール・マネージャのルール・クラスには、ルール定義とともに任意の形式(スカラー、XML、RAW、BLOBなど)のデータを格納できます。このデータは、対応するルールがイベントに一致すると、アクション・コールバック・プロシージャまたはアプリケーションに戻されます。
たとえば、ルール・アプリケーションでは、Simple Object Access Protocol(SOAP)メッセージを各ルールのアクションとして完全な形式で(XMLType
列に)格納することもできます。この場合、ルールがイベントに一致すると、このSOAPメッセージはアプリケーションに戻されます。中間層のアプリケーションは、データを適切に解釈し、必要なアクション(SOAPメッセージの転送)を実行します。アクション実行の追加情報は、付録Gを参照してください。
別のアプリケーションでは、アクションに対する正確なコールを固定できます。たとえば、OfferDiscount2Customer
関数を使用する場合です。この場合、ルール定義には提供する値引率のみを格納できます。この値引値は、アプリケーションに戻されるとき、引数としてOfferDiscount2Customer
関数コールにバインドできます。