1

まず時間を放棄してきました。皆さんありがとう!私が持っているTomcatの8の接続が質問を投稿

問題はしばらくの間、周りされていると、私たちはそのための解決策を見つけることができませんでした。つまり、Java 8、Spring、Hibernate、PostgreSQL、JSF(ここではPrimeFaces)、Webflowを使用してアプリケーションをビルドします。 接続がクローズされることに関連した問題が、アプリケーションがまだので、次回は、いくつかのロジックが同じ接続それそれのちょうど「つまずき」を借用し、例外をスローし、それを使用しているようです:

アプリケーションのために働く可能性があり
Caused by: org.hibernate.exception.GenericJDBCException: could not prepare statement 
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47) 

Caused by: java.sql.SQLException: Connection has already been closed. 
    at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:117) 
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:108) 

何も起こらなくなるまで、何の問題もなくカップルの日が過ぎて、ConnectionはTomcatから警告を放棄した。

WARNING [Tomcat JDBC Pool Cleaner[1989780873:1502425160484]] org.apache.tomcat.jdbc.pool.ConnectionPool.abandon Connection has been abandoned PooledConnection[[email protected]]:java.lang.Exception 
    at org.apache.tomcat.jdbc.pool.ConnectionPool.getThreadDump(ConnectionPool.java:1093) 

私たちのチームは、Webで検索、その問題に時間と時間を過ごす:うまく動作しません、との接続が既に閉じられているため、多くのプロセスが、その閉じられた接続になるだろうし、測定可能失敗しますがありますから、 、そして仲間の開発者と相談して、当初はTomcat server.xmlを微調整しようとしていましたが、成功することはありませんでした。それは別の日にうまく動くかもしれませんし、同じ問題でサーバが矛盾するところで失敗するかもしれないので、唯一行うことはそれを再起動することです。私たちが追加したインターセプタは、問題を解決しようとするのに役立ちませんでした。

のみ後、私たちは確実に問題を複製することができ、そして問題が独自にかなり面白かったです。したがって、NoResultExceptionがある場合や、アサーションに基づいてMyCustomExceptionがスローされた場合など、トランザクション、カスタムJavaまたは標準Javaでスローされた例外が発生した場合、Tomcatは放棄されたConnectionを閉じます(閉じます)。 60秒後(removeAbandonedTimeout)警告メッセージが表示され、接続が閉じられます。しかし、ロジックが引き続きそれを参照し、より多くの接続がラインを閉じるという問題は、ビジネスロジックの実行中により多くのことが壊れます。

server.xmlで構成された2つのデータソースがあります(ビジネスロジックのための1は、ジョブの別)は次のように:

<Resource auth="Container" driverClassName="org.postgresql.Driver" 
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" 
initialSize="5" 
jdbcInterceptors= 
"org.apache.tomcat.jdbc.pool.interceptor.ConnectionState; 
org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer; 
org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReportJmx (threshold=10000)" 
logAbandoned="true" 
maxActive="30" 
minEvictableIdleTimeMillis="30000" 
minIdle="5" 
name="jdbc/my-app-db" 
password="" 
removeAbandoned="true" 
removeAbandonedTimeout="60" 
testOnBorrow="true" 
testOnReturn="false" 
testWhileIdle="true" 
timeBetweenEvictionRunsMillis="5000" 
type="javax.sql.DataSource" 
url="jdbc:postgresql://mydb.rds.amazonaws.com:5432/mydb_db" 
username="" 
validationInterval="30000" 
validationQuery="SELECT 1" /> 

<Resource auth="Container" 
driverClassName="org.postgresql.Driver" 
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" 
initialSize="5" 
jdbcInterceptors= 
"org.apache.tomcat.jdbc.pool.interceptor.ConnectionState; 
org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer; 
org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReportJmx (threshold=10000)" 
logAbandoned="true" 
maxActive="30" 
minEvictableIdleTimeMillis="30000" 
minIdle="5" 
name="jdbc/my-app-db-for-jobs" 
password="" 
removeAbandoned="true" 
removeAbandonedTimeout="60" 
testOnBorrow="true" 
testOnReturn="false" 
testWhileIdle="true" 
timeBetweenEvictionRunsMillis="5000" 
type="javax.sql.DataSource" 
url="jdbc:postgresql://mydb.rds.amazonaws.com:5432/myapp_db" 
username="" 
validationInterval="30000" 
validationQuery="SELECT 1" /> 

とXML構成:一部で

<bean id="entityManagerFactory" 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="persistenceUnitName" value="acme"></property> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
      <property name="showSql" value="true" /> 
      <property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect" /> 
     </bean> 
    </property> 
</bean> 
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="dataSource" ref="dataSource"></property> 
    <property name="entityManagerFactory" ref="entityManagerFactory"></property> 
</bean> 

とのpom.xml依存関係:

<dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-validator</artifactId> 
     <version>5.2.4.Final</version> 
    </dependency> 

    <dependency> 
     <groupId>org.springframework.webflow</groupId> 
     <artifactId>spring-faces</artifactId> 
     <version>2.4.2.RELEASE</version> 
    </dependency> 

    <dependency> 
     <groupId>org.springframework.webflow</groupId> 
     <artifactId>spring-webflow</artifactId> 
     <version>2.4.2.RELEASE</version> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-context-support</artifactId> 
     <version>4.1.6.RELEASE</version> 
    </dependency> 

    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-web</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-entitymanager</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>org.postgresql</groupId> 
     <artifactId>postgresql</artifactId> 
     <version>42.1.1</version> 
    </dependency> 

ここでは失敗する可能性のあるコードがありますが、

PromoCode promoCodeEntity = null; 
    try { 
     JpaTransactionManager transactionManager = (JpaTransactionManager) ApplicationContextProvider 
       .getApplicationContext().getBean("transactionManager"); 
     TransactionDefinition def = new DefaultTransactionDefinition(); 
     TransactionStatus status = transactionManager.getTransaction(def); 

     String jpql = "select p from PromoCode p where p.code = :code"; 
     Query query = em.createQuery(jpql).setParameter("code", promoCode); 
     promoCodeEntity = (PromoCode) query.getSingleResult(); 

     if (promoCodeEntity.getQuantyOfUses() >= promoCodeEntity.getTotalOfUses()) { 
      MyCustomException myCustomException = new MyCustomException("This promo code is not valid: [" + promoCode + "]"); 
      MyCustomException.setCode("PROMO_CODE"); 
      throw myCustomException; 
     } 

     if (!promoCodeEntity.getActive() || promoCodeEntity.getFinish()) { 
      MyCustomException myCustomException = new MyCustomException("This promo code is not valid: [" + promoCode + "]"); 
      myCustomException.setCode("PROMO_CODE"); 
      throw myCustomException; 
     } 

     if (!(promoCodeEntity.getStartDateValid().before(new Date()) 
       && promoCodeEntity.getEndDateValid().after(new Date()))) { 
      MyCustomException myCustomException = new MyCustomException("This promo code is expired: [" + promoCode + "]"); 
      myCustomException.setCode("PROMO_CODE"); 
      throw myCustomException; 
     } 
     promoCodeEntity.setQuantyOfUses(promoCodeEntity.getQuantyOfUses() + 1); 
     transactionManager.commit(status); 
    } catch (NoResultException e) { 
     MyCustomException myCustomException = new MyCustomException("Promo code not found: [" + promoCode + "]"); 
     myCustomException.setCode("PROMO_CODE"); 
     throw myCustomException; 
    } 

は、誰もがこのような問題が発生したのか、私はさらにどこを見てください。DBが閉じたプールたっつまずく可能性が照会トランザクション、または何かを持っているLLY何?私たちは、c3p0 Poolを現在評価している、これがTomcat Poolのバグ関連であるかどうかを確認するために、いくつかのドライバの更新(postgres jdbcなど)を行いました。しかし、間違っていることを理解することは本当にうれしいです。

答えて

0

あなたのdataSourcesプロパティにconnectionTimeoutを使用することを旧姓。現在、デフォルトのタイムアウトを使用しています。タイムアウト後、セッションを強制的にクローズします。あなたはdataSourcesプロパティにコードの下に追加しようとすることができます。

 connectionTimeout="300000" 
0

はあなたC3P0のプロパティを変更してください。 unreturnedConnectionTimeoutは接続のハングを処理します。クエリに時間がかかり過ぎると、接続がタイムアウトしてdb接続がハングしてしまいます。接続が制限されているため、このプロセスが繰り返されると接続が枯渇する可能性があります。 testConnectionOnCheckoutは、接続が閉じられているかどうかをチェックし、閉じていない場合は閉じます。

c3p0.unreturnedConnectionTimeout=2000 
c3p0.testConnectionOnCheckout=true 
+0

お返事ありがとうございました。この問題は、クエリーが長時間かかることとは関係ありませんが、今はできません。私たちは現在、HikariCP Poolでセットアップを行っていますが、問題は見えなくなりませんでした。接続は使い果たされるかもしれませんが、クエリのタイムアウトの理由以外の理由があります。 – user3711719