2

私のアプリケーションは JPA(Hbernate ORM) を使用して、JBoss AS 7.x サーバーにデプロイされた SQL サーバー 2008 に接続しています。ネットワークがダウンして再びアップした場合、次の例外が発生します

14:59:27,996 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: The connection is closed.
14:59:28,002 ERROR [stderr] (http-localhost-127.0.0.1-8080-1)   at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1361)
14:59:28,012 ERROR [stderr] (http-localhost-127.0.0.1-8080-1)   at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1289)
14:59:28,020 ERROR [stderr] (http-localhost-127.0.0.1-8080-1)   at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:261)
14:59:28,025 ERROR [stderr] (http-localhost-127.0.0.1-8080-1)   at com.honeywell.domoweb.dataservice.dao.impl.UserDaoImpl.getUsers(UserDaoImpl.java:372)
14:59:28,030 ERROR [stderr] (http-localhost-127.0.0.1-8080-1)   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
14:59:28,034 ERROR [stderr] (http-localhost-127.0.0.1-8080-1)   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
14:59:28,039 ERROR [stderr] (http-localhost-127.0.0.1-8080-1)   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
14:59:28,044 ERROR [stderr] (http-localhost-127.0.0.1-8080-1)   at java.lang.reflect.Method.invoke(Method.java:597)
14:59:28,047 ERROR [stderr] (http-localhost-127.0.0.1-8080-1)   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)
14:59:28,052 ERROR [stderr] (http-localhost-127.0.0.1-8080-1)   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
14:59:28,058 ERROR [stderr] (http-localhost-127.0.0.1-8080-1)   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
14:59:28,064 ERROR [stderr] (http-localhost-127.0.0.1-8080-1)   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
14:59:28,069 ERROR [stderr] (http-localhost-127.0.0.1-8080-1)   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
14:59:28,075 ERROR [stderr] (http-localhost-127.0.0.1-8080-1)   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
14:59:28,080 ERROR [stderr] (http-localhost-127.0.0.1-8080-1)   at $Proxy66.getUsers(Unknown Source)
14:59:28,083 ERROR [stderr] (http-localhost-127.0.0.1-8080-1)   at com.honeywell.domoweb.dataservice.dao.impl.TemplateDaoImpl.getTemplate(TemplateDaoImpl.java:44)
14:59:28,089 ERROR [stderr] (http-localhost-127.0.0.1-8080-1)   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)...

この問題をグーグルで調べたところ、autoReconnect 属性を使用して再接続するには接続プールの構成を変更する必要があることがわかりましたが、autoReconnect を接続プールの設定に埋め込む方法の例は見つかりませんでした。以下は接続プールの設定です。 Standalone.xml ファイル内

<subsystem xmlns="urn:jboss:domain:datasources:1.0">
        <datasources>


            <datasource jndi-name="java:jboss/datasources/DataServiceDS" pool-name="dataServicePool" enabled="true" use-java-context="true">
                <connection-url>jdbc:sqlserver://ipaddress:1433;databaseName=myDataBase</connection-url>
                <driver>sqlserver</driver>
                <pool>
                    <min-pool-size>10</min-pool-size>
                    <max-pool-size>100</max-pool-size>
                    <prefill>true</prefill>
                </pool>
                <security>
                    <user-name>usename</user-name>
                    <password>password</password>
                </security>
            </datasource>
            <drivers>

                <driver name="sqlserver" module="com.microsoft.sqlserver">
                    <xa-datasource-class>com.microsoft.sqlserver.jdbc.SQLServerDriver</xa-datasource-class>
                </driver>
            </drivers>
        </datasources>
    </subsystem>

ネットワークがダウンして再接続された場合、データベースに再接続する方法を教えてください。

4

3 に答える 3

6

追加できます

<check-valid-connection-sql>select 1 </check-valid-connection-sql>

データソース構成、または必要なその他の SQL ステートメントに追加します。このSQLステートメントは、接続が接続プールからチェックアウトされるたびに実行され、ステートメントが失敗した場合、つまり接続が閉じられた場合、それは破棄され、SQLサーバーに再作成/再接続されます. これにより、アプリケーション(休止状態)が常にSQL接続を機能させることができます。

于 2012-11-02T01:04:22.413 に答える
3

また、同様の問題の例を見つけるのに苦労しました。jboss7 の場合、次の行をデータソース設定に追加しました

<datasource>
  ...
  <validation>
    <check-valid-connection-sql>select 1 from dual</check-valid-connection-sql>
    <validate-on-match>false</validate-on-match>
    <background-validation>true</background-validation>
  </validation>
  ...
</datasource>
于 2014-04-04T07:43:36.940 に答える
2

何を修正しようとしていますか?

「ネットワークがダウンした」ときにトランザクションが失敗するのを止めようとしている場合。それは不可能です。その問題の一部を解決するには、「XA」と SQL クラスタリングを調べる必要があります。しかし、私はあなたがこれを探しているとは思わない.

..

JBoss の接続プーラーが保持していたアイドル状態の SQL 接続の最初のユーザーになってしまった場合にアプリケーション操作が失敗するのを防ぎたい場合。それなら、できることはあります。

問題は:

  • Windows はデフォルトで、「ネットワークがダウンした」ときにアクティブな TCP 接続を切断します。他のプラットフォームではこれを行いません。あなたにとって、ネットワークの一部だけがダウンすると思います。つまり、影響を受けた場合、SQL サーバーは終了しますが、JBoss は終了しません。

  • JBoss エンドの接続プーラーは、プール内のアイドル状態の接続で TCP 接続を開いたままにします。JBoss エンドは、ネットワークがダウンしたことを認識しないため、SQL サーバーとの接続が短時間失われる可能性があります。ネットワークが起動すると、SQL サーバーがリセットされ、すべての接続が失われます。しかし、JBoss エンドにはまだ「ハーフ オープン接続」があり、接続が有効であると考えられています。

  • JBoss エンドは、SQL を処理する必要がある前に、しばらく (秒/分/時間) アイドル状態になる可能性があります。次に SQL ハンドルを取得し、接続プーラーはプールからアイドル状態のハンドルを適切に返します。TCP 接続が停止していることを知らない。次に、アプリケーションはそれを使用して、クライアントからサーバーに送信された一部のデータに応答して TCP 接続がリセットされ、サーバーが「その接続を開いていません」と言っているかどうかを確認します。これにより、SQL ドライバーは強制的に接続を閉じ、JDBC ハンドルの操作に SQLException を返し始めます。

以下では、問題を軽減または解決する方法について一般的な用語で説明します。サポート チャネルと SQL ドキュメントを参照してください。

調べること:

  • 接続プーラーのドキュメント。JBoss は独自の接続プール実装を提供していると思います。したがって、この問題は接続プーラーで解決できるのは事実ですが、お使いの JBoss バージョンの接続プーラーと、既に使用しているバージョンに機能が備わっている可能性があるかどうかは明らかではありません。

  • TCP キープアライブを有効にします。これらは TCP プロトコルによって実行される低レベルの ping/pong で、通常は数秒かかります。デフォルトの 1 時間は SQL には長すぎるかもしれませんが、5 分のほうがよいでしょう。

  • 接続プーラーを有効にして、アプリケーションに渡す前に、接続が良好で有効であることを確認/検証します。これは、内部の ping/pong チェックを使用するか、「SELECT 1」を実行する可能性があります。これはおそらく、問題を完全に修正するための最も簡単で迅速な解決策ですが、使用前に余分なラウンドトリップが発生するため、パフォーマンスにかなりの影響を与える可能性があります。

  • 上記のポイントは、接続が一定の制限 (おそらく 60 秒) より長くアイドル状態である場合にのみ有効にしてください。これにより、SQL がかなりアイドル状態のときに有効にすることによるパフォーマンスへの影響が軽減されます。

  • SQL ドライバーがカスタム TCP データの ping/pong メカニズムをサポートしているかどうかを確認し、接続プーラーの実装がそれをサポートしているかどうかを確認してください。

  • 短い最大アイドル時間を使用します。

  • アイドル接続の最大数を減らします。

  • 接続がトランザクション内になく、これが失敗した最初のステートメントである場合は、自動再接続を有効にします (多くの場合、唯一のオプションの変更は autocommit=off であり、「BEGIN TRANSACTION」です。この状況は、ドライバーが検出してシームレスに回復する可能性があります)。 .

外部のサード パーティ製オープン ソース プーラーを使用する選択肢がある場合は、c3p0 接続プーラーを検討することをお勧めします。これは、JBoss 環境では当てはまらない場合があります。

于 2012-10-25T10:37:17.133 に答える