1

Android をクライアントとして、JBoss AS 7.x をサーバーとして使用して、クライアント/サーバー アプリケーションを開発しています。私はサーブレットを介してこれらすべてを行っており、DataSource は接続プールを利用するように構成されています。

要件の 1 つは、DataSource(Oracle) から特定のデータが削除されたときにクライアント セッションを直ちに無効にすることです。このために、DBMS_ALERT をチェックしていました。

私が理解できる限り、DBMS_ALERT には、通知が発生するまでアプリケーションを「ハング」させるポーリング メカニズムが必要です。したがって、私のサーブレットはすべての操作を停止し、通知を待ちます。PL/SQL の経験がほとんどないため、間違っている場合は訂正してください。

この質問で提供されているリソースを既に確認しましたが、どの道を進むべきかを理解できませんでした。


DBMS_ALERT DataSource側のコードは次のとおりです。

CREATE OR REPLACE TRIGGER apps0000_datuser_biur
    BEFORE  INSERT OR UPDATE OR DELETE on apps0000_t
    REFERENCING NEW AS NEW OLD AS OLD
    for EACH ROW
begin
    if (deleting) then
        DBMS_ALERT.signal('appdelete',:old.APPS_PACKAGE);
    end if;
end;


DBMS_ALERTサーブレット側のコードは次のとおりです (ここで何か問題があった場合は修正してください)。

try {
    String strDSName1 = "java:/OracleDSJNDI";
    ctx = new InitialContext();
    ds1 = (javax.sql.DataSource) ctx.lookup(strDSName1);
} catch (Exception e) {
    System.out.println("ERROR getting 1'st DS : " + e);
}

 conn = ds1.getConnection();

 String sql = null;
 String message = null;
 String status = null;

 sql = "{call dbms_alert.register('appdelete')}";
 CallableStatement cs1 = conn.prepareCall(sql);
 cs1.execute();
 sql = "{call dbms_alert.waitone('appdelete', ?, ?, ?)}";

 CallableStatement cs2 = conn.prepareCall(sql);
 cs2.registerOutParameter(1, Types.VARCHAR);
 cs2.registerOutParameter(2, Types.VARCHAR);
 cs2.registerOutParameter(3, Types.VARCHAR);

 int x = 0;

 while (x == 0) {
     cs2.execute();
     String Result = cs2.getString(1);
     System.out.print(Result + "\n");
 }


私の質問は次のとおりです: DBMS_ALERT 部分に到達したときにハングすることなく、サーブレットにこれを実装するにはどうすればよいですか (それが実行可能な解決策である場合)。

ありがとう

4

1 に答える 1

2

API ドキュメントのメッセージ関数を見ると、次のように表示されます。

DBMS_ALERT.WAITONE (
   name      IN   VARCHAR2,
   message   OUT  VARCHAR2,
   status    OUT  INTEGER,
   timeout   IN   NUMBER DEFAULT MAXWAIT);

「タイムアウト」パラメータのデフォルトは無期限です。コメントには次のように記載されています。

timeout

Maximum time to wait for an alert.

If the named alert does not occurs before timeout seconds, this returns a status of 1.

したがって、このタイムアウトを数秒に設定してから、ループでポーリングすることができます。ただし、ポーリングを使用してネットワークとアプリケーション/サーバーのリソースを消費しているだけなので、これは貧弱なアプローチであると主張します。可能であれば、完全な非同期処理を可能にする Oracle Advanced Queueing の使用を検討します (DBMS_AQ パッケージを参照)。

于 2013-09-12T22:11:25.207 に答える