2

私は、EclipseLinkJPAを使用して永続層を処理するTomcat7にデプロイされたWebアプリケーションに取り組んできました。

テスト環境ではすべて正常に動作しますが、ファイアウォールが切断されて非アクティブな接続が切断されるため、本番環境で深刻な問題が発生しています。基本的に、接続がしばらく非アクティブである場合、TomcatサーバーとDBサーバーの間にファイアウォールがあり、それを強制終了します。その結果、プールに「古い」接続が残ります。

次にその接続が使用されるとき、「接続がタイムアウトした」SQLException(以下の完全なex.getMessage())を取得するまで、コードは返されません。

EL Fine]:2012-07-13 18:24:39.479--ServerSession(309463268)--Connection(69352859)--Thread(Thread [http-bio-8080-exec-5,5、main])-MY SOに投稿するために置き換えられたクエリ[ELConfig]:2012-07-13 18:40:10.229--ServerSession(309463268)--Connection(69352859)--Thread(Thread [http-bio-8080-exec-5、 5、main])--disconnect [EL Info]:2012-07-13 18:40:10.23--UnitOfWork(1062365884)--Thread(Thread [http-bio-8080-exec-5,5、main]) -トランザクションの外部で読み取りクエリを実行しようとしたときに、通信障害が検出されました。クエリを再試行しています。エラーは次のとおりです:例外[EclipseLink-4002](Eclipse Persistence Services-2.3.0.v20110604-r9504):org.eclipse.persistence.exceptions.DatabaseException内部例外:java.sql.SQLException:Eccezione IO:接続がタイムアウトしました

私はすでにpersistence.xmlでいくつかの構成を試しましたが、ファイアウォール構成にアクセスできないため、これらの方法ではうまくいきませんでした。setCheckConnections()も使用してみました

ConnectionPool cp = ((JpaEntityManager)em).getServerSession().getDefaultConnectionPool();
        cp.setCheckConnections();
        cp.releaseConnection(cp.acquireConnection());

testOnBorrow、testWhileIdle、およびDBCP Apache Commonsから利用可能なその他の機能を使用して、テストスクリプトで問題を解決することができました。EclipseLink内部接続プールをオーバーライドしてカスタム接続プールを使用する方法を知りたいので、persistence.xmlを使用して内部プールを構成するだけでなく、DBCPに基づいて構成済みのプールを提供できます。

SessionCustomizerを提供する必要があることはわかっていますが、どちらを使用するのが正しいかわかりません。基本的に、JPAのような方法でDBCPのパフォーマンスを維持したいと思います。

私はTomcat7にデプロイしていますが、GFに切り替えてもこの問題は発生しないことはわかっていますが、同じサーバー上の他のWebアプリケーションとの一貫性を保つために、Tomcatを使用したいと思います。

4

1 に答える 1

3

あなたが望むことは間違いなく可能ですが、あなたは「自分でやる」アプローチの限界に達しているかもしれません。

これは説明が難しいことの1つですが、を構成するには事実上2つの方法がありますEntityManagerFactory。「自分でやる」アプローチと「コンテナ」アプローチ。

呼び出すPersistence.createEntityManagerFactoryと、最終的にPersistenceProviderEclipseLinkによって実装されたインターフェイスのこのメソッドに委任されます。

EntityManagerFactory    createEntityManagerFactory(String emName, Map map) 

ここでの取り決めは、EclipseLinkがそれ自体を引き受けて、独自の接続の作成と処理を含むすべての作業を実行することです。これは「自分でやる」アプローチです。このアプローチを使用して接続をフィードする方法があるかどうかを知るのに十分なほどEclipseLinkを知りません。Stackoverflowで2日間過ごした後、他の誰もその情報を持っていないようです。

これが「GFで機能する」理由です。EntityManagerFactoryコンテナに挿入または検索してコンテナを作成させると、コンテナはPersistenceProviderEclipseLinkによって実装されたインターフェイスで別のメソッドを使用します。

EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map map) 

その長所と短所は、これPersistenceUnitInfoがコンテナが実装するインターフェースであり、次の2つの非常に重要なメソッドを備えていることです。

public DataSource getJtaDataSource();
public DataSource getNonJtaDataSource();

このモードでは、EclipseLinkは独自の接続処理を実行しようとせず、単にこれらのメソッドを呼び出しDataSourceてコンテナーからを取得します。これは本当にあなたが必要なものです。

これを解決するために取ることができる2つの可能なアプローチがあります:

  • EclipseLink実装を自分でインスタンス化して、インターフェイスの独自の実装を渡すメソッドをPersistenceProvider呼び出し、その方法でDBCP構成済みインスタンスをEclipseLinkにフィードすることができます。ファイルを自分で解析し、そのデータを。を介してフィードする必要があります。同様に、EclipseLinkもを期待する可能性があります。その場合、Tomcatに追加できるTransactionManagerを探し出さない限り、スタックします。createContainerEntityManagerFactoryPersistenceUnitInfoDataSourcepersistence.xmlPersistenceUnitInfoTransactionManager

  • TomcatのJavaEE6認定バージョンであるTomEEを使用できます。データソースはで構成され、tomee.xml必要なすべてのオプションを完全にサポートするDBCPを使用して作成されPersistenceProvider、説明されている呼び出しを使用してに渡されcreateContainerEntityManagerFactoryます。次に、EntityManagerFactoryを介して注入される@PersistenceUnitか、それを調べます。

TomEEを使用する場合は、デフォルトが。であるため、persistence.xml明示的に設定されるように更新されていることを確認してください。このアプローチで使用することは非準拠ですが、不平を言ってあなたが間違ったことをしていることを知らせる永続化プロバイダーはありません。彼らはそれをスキーマを無視するものとして扱います。そのため、アプリを実際の認定サーバーに移植すると、爆発します。transaction-type="RESOURCE_LOCAL"JTAJTAPersistence.createEntityManagerFactoryRESOURCE_LOCAL

TomEEに関するもう1つの注意点は、現在のリリースでは、EclipseLinkライブラリを<tomcat>/lib/ディレクトリに配置する必要があるということです。これはトランクで修正されていますが、まだリリースされていません。

これらのスライドに付随する説明がなければ、これらのスライドがどれほど役立つかはわかりませんが、このプレゼンテーションの後半では、特に接続処理とトランザクションに関して、コンテナ管理のEntityManagerの動作について詳しく説明します。トランザクション部分は使用しておらず、すでに本番環境にあるため、劇的に変更される可能性は低いため、無視できますが、将来の開発には役立つ可能性があります。

頑張ってください!

于 2012-07-20T15:20:21.757 に答える