1

JBoss AS 7.1 をサーバーとして使用しており、DataSource をプーリングで構成しています。私はこれにまったく慣れていないので、初心者の間違いを許してください...結局のところ、私は学ぶためにここにいます.

クライアントがログインすると、データベースへの接続が確立され、ユーザーがログアウトするか HttpSession の有効期限が切れるまで、(プールからの) その接続を開いたままにしておく必要があります。これは、DB 管理者からの絶対的な要件です。誰がDBセッション変数が必要だと言っています。これらすべてにサーブレットを使用しています。

私が遭遇した2つの大きな問題:

  1. 私が見る限り、JBoss は未使用の接続を自動的に閉じます => 開いた接続はプールに戻ります。したがって、これは正しい道ではないかもしれません。

  2. 次のように接続オブジェクトを保存/リコールしようとすると:

    private Hashtable<String, Connection> connections = new Hashtable<String, Connection>();
    
    try {
        String strDSName1 = "java:/OracleDSJNDI";
        ctx = new InitialContext();
        ds1 = (javax.sql.DataSource) ctx.lookup(strDSName1);
    
        System.out.println("Got 1'st ds.");
    
    } catch (Exception e) {
        System.out.println("ERROR getting 1'st DS : " + e);
    }
    
    connection = ds1.getConnection();
    connections.put(session.getId(), connection);
    
    conn = (Connection) connections.get(sessionID);
    

    次の例外がスローされます。

    java.sql.SQLException: 接続が管理された接続に関連付けられていません.org.jboss.jca.adapters.jdbc.jdk6.WrappedConnectionJDK6@dee1f37



私の質問は次のとおりです。接続を適切に開いたままにするにはどうすればよいですか?

ありがとう

4

2 に答える 2

6

接続を適切に開いたままにするにはどうすればよいですか?

接続プールにこれを処理させてください


舞台裏では、接続プールはデータベース エンジン (MySQL、Oracle、SQL Server など、構成方法によって異なります) への多数のデータベース接続を保持しますSLEEPING。このコードを実行すると:

//avoiding all the particular exceptions just for code simplicity purposes...
//in real world applications, you must handle each of these exceptions
public Connection getConnection() throws Exception {
    ctx = new InitialContext();
    ds1 = (javax.sql.DataSource) ctx.lookup(strDSName1);
    return ds1.getConnection();
}

使用可能なこれらの接続の 1 つを取得するように接続プールに要求しています。接続プールは、データベース接続 (利用可能な場合) を提供し、必要なだけ使用できるようにします。次に、必要な場所で使用して閉じます

public void foo() throws Exception {
    Connection connection = getConnection();
    //do what you want/need...

    //in the end, you close the connection
    //this is A MUST!
    connection.close();
}

接続プールによって取得された接続から実行する場合connection.close()、物理的なデータベース接続を閉じることはありませんが、この特定のデータベース接続がSLEEPING状態に戻る必要があることを接続プールに通知します。


説明からのいくつかのアドバイス:

  • 接続を維持しようとしないでください。それは接続プールの仕事です。
  • 接続をキャッシュのような構造に格納しようとしてはなりませ。これは接続プールの仕事です。
  • 必要な最短のスコープで を取得する必要があります。java.sql.Connection使い終わったら閉じてください。
于 2013-09-11T19:04:29.690 に答える
2

DBA は基本的に、データベース接続をユーザーのセッションと同等にすることで、接続プーリングを回避するように要求しています。

したがって、1 つのオプションは、接続プールを使用せず、代わりに、ユーザーのセッションでデータベース接続を開閉する独自の機能をロールバックすることです。しかし、それは複雑で珍しいようです。

もう 1 つのオプションは、DBA の要件を調べることです。DBA は、別の方法で状態を追跡する必要があるという考えに適応しなければならない場合があります。たとえば、セッションに関連するキーを使用して、必要な状態をテーブルに格納するのではなく、接続レイヤーに状態を格納します。

一般的に言えば、一部のコンポーネントのセッション処理で状態を保存すると、間接的な複雑さが増します。これは、コンポーネントが有効期限と一意性を処理する方法を気にする必要があるためです。ここで、HTTP セッション状態がデータベース セッションとは異なる方法でこれを処理する場所を見つけます。

于 2013-09-11T19:22:48.707 に答える