2012-12-03 19 views
5

के साथ पोस्टग्रेस में ऑटो-रीकनेक्ट जहां तक ​​मैं समझता हूं, "testOnBorrow" और "validationQuery" पैरामीटर मेरी गली पर सही हैं लेकिन वे अपेक्षा के अनुसार काम नहीं कर रहे हैं।टॉमकैट पूल और वसंत

मैं एप्लिकेशन को शुरू करता हूं, कुछ प्रश्न चलाता हूं और सब ठीक हो जाता है। तब मैं postgres सर्वर को पुनः आरंभ - बिल्ला को पुन: प्रारंभ बिना - डेटा स्रोत का परीक्षण करने के लिए फिर से कनेक्शन संभाल कर सकते हैं और सभी मैं यह है:

This connection has been closed.; nested exception is org.postgresql.util.PSQLException: This connection has been closed. 
    at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:104) 
     at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72) 
     at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80) 
     at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80) 
     at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:603) 
     at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:637) 
     at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:666) 
     at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:674) 
    at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:729) 

... 

Caused by: org.postgresql.util.PSQLException: This connection has been closed. 
    at org.postgresql.jdbc2.AbstractJdbc2Connection.checkClosed(AbstractJdbc2Connection.java:822) 
    at org.postgresql.jdbc3.AbstractJdbc3Connection.prepareStatement(AbstractJdbc3Connection.java:273) 
    at org.postgresql.jdbc2.AbstractJdbc2Connection.prepareStatement(AbstractJdbc2Connection.java:301) 
    at sun.reflect.GeneratedMethodAccessor38.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:601) 
    at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:126) 
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:99) 
    at org.apache.tomcat.jdbc.pool.interceptor.AbstractCreateStatementInterceptor.invoke(AbstractCreateStatementInterceptor.java:67) 
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:99) 
    at org.apache.tomcat.jdbc.pool.interceptor.ConnectionState.invoke(ConnectionState.java:153) 
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:99) 
    at org.apache.tomcat.jdbc.pool.TrapException.invoke(TrapException.java:41) 
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:99) 
    at org.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:63) 
    at $Proxy35.prepareStatement(Unknown Source) 
    at org.springframework.jdbc.core.JdbcTemplate$SimplePreparedStatementCreator.createPreparedStatement(JdbcTemplate.java:1436) 

मैं उपयोग कर रहा हूँ:

  • स्प्रिंग 3.1
  • PostgreSQL 9.2.1
  • कनेक्शन के पूल: org.apache.tomcat.jdbc.pool 7.0.25

मेरे वसंत सेम conf iguration निम्नानुसार है:

public DataSource dataSource() { 
    org.apache.tomcat.jdbc.pool.DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource(); 
    // from properties file 
    dataSource.setDriverClassName(environment 
      .getProperty("datasource.driver")); 
    dataSource.setUrl(environment.getProperty("datasource.url")); 
    dataSource.setUsername(environment.getProperty("datasource.username")); 
    dataSource.setPassword(environment.getProperty("datasource.password")); 
    // other configurations 
    dataSource.setInitialSize(10); 
    dataSource.setMinIdle(10); 
    dataSource.setMaxIdle(100); 
    dataSource.setMaxActive(100); 
    dataSource.setDefaultAutoCommit(true); 
    dataSource.setMaxWait(6000); 
    dataSource.setJmxEnabled(true); 
    dataSource 
      .setJdbcInterceptors("....ConnectionState;.....StatementFinalizer"); 
    dataSource.setRemoveAbandoned(true); 
    dataSource.setRemoveAbandonedTimeout(10); 
    dataSource.setLogAbandoned(true); 
    dataSource.setTestOnBorrow(true); 
    dataSource.setTestOnReturn(false); 
    dataSource.setTestWhileIdle(false); 
    dataSource.setUseEquals(false); 
    dataSource.setFairQueue(false); 
    dataSource.setTimeBetweenEvictionRunsMillis(30000); 
    dataSource.setMinEvictableIdleTimeMillis(30000); 
    dataSource.setValidationInterval(1800000); 
    dataSource.setValidationQuery("SELECT 1"); 

    return dataSource; 
} 

कोई विचार?

धन्यवाद

उत्तर

1

कनेक्शन का सत्यापन ही किया जाता है जब यह शुरू में पूल से लिया गया है। भले ही इसे प्रत्येक क्वेरी से पहले चेक किया गया हो, फिर भी चेक और क्वेरी के बीच समय की अवधि होगी जहां कनेक्शन खोया जा सकता है। सभी प्रश्नों में क्वेरी विफलता से निपटने के लिए अपवाद हैंडलिंग का कुछ रूप होना चाहिए - सामान्य रूप से, खराब कनेक्शन हैंडल का निपटान करना, एक नया प्राप्त करना, और क्वेरी को पुनः प्रयास करना (यदि संभव हो)।

जेडीबीसी मानक में "कनेक्शन एररऑक्चर" की कॉलबैक विधि है जिसे कभी भी ऐसा कुछ कहा जाता है, लेकिन मुझे यह पता नहीं है कि जेडीबीसी और जावा कैसे इसका उपयोग करने के लिए काम करता है (या यहां तक ​​कि अगर यह इस मामले को कवर करता है)।

किसी भी मामले में, जब आप कनेक्शन का उपयोग करने का प्रयास करते हैं तो केवल एक बार अच्छा या बुरा होता है, तो कनेक्शन के निष्पादन और पुनः प्रयास करने के लिए कोई कस्टम पूल स्वचालित रूप से उस समस्या को दूर नहीं कर सकता है , जो मानक इंटरफेस में जेडीबीसी "अनुबंध" तोड़ देगा।

1

मुझे हाल ही में नेटवर्क ड्रॉप होने पर टोमकैट जेडीबीसी कनेक्शन पूल को फिर से कनेक्ट करने की इच्छा रखने की एक ही समस्या है। आप की तरह, मुझे परीक्षण भी मिला है कल और सत्यापन अंतराल मेरे लिए नौकरी नहीं करता है।

मैं अंततः जेडीबीसी टेम्पलेट पर एक सलाह तैयार करने के लिए समाप्त हुआ (हम वसंत के org.springframework.jdbc.core.JdbcTemplate का उपयोग करते हैं) और सलाह के अंदर पुनः प्रयास करता है।

स्प्रिंग विन्यास इस तरह दिखता है:

<bean id="jdbcRetryOnFailureAdvice" class="my.jdbc.adapter.JdbcRetryOnFailureAdvice"> 
    <property name="maxRetriesOnConnDrop" value="5"/> 
    <property name="retryWaitInMillis" value="5000"/> 
    <property name="sqlStatesToRetry" value="08003 08001 57P01"/> 
</bean> 

<aop:config proxy-target-class="true"> 
    <aop:aspect id="jdbcRetryOnUpdate" ref="jdbcRetryOnFailureAdvice"> 
     <aop:pointcut id="retryUpdatePointCut" 
         expression="execution(* 
         org.springframework.jdbc.core.JdbcTemplate.update(..))"/> 
     <aop:around pointcut-ref="retryUpdatePointCut" 
         method="retryOnFailure"/> 
    </aop:aspect> 
</aop:config> 

my.jdbc.adapter.JdbcRetryOnFailureAdvice वर्ग इस तरह दिखता है:

public class JdbcRetryOnFailureAdvice { 

    private int maxRetriesOnConnDrop = 0; 

    private long retryWaitInMillis = 1000; 

    public Object retryOnFailure(ProceedingJoinPoint jp) throws Throwable { 
     Object result = null; 
     int retryCount = 0; 
     do { 
      try { 
       Object[] args = jp.getArgs(); 
       if (args != null && args.length > 0) 
        result = jp.proceed(jp.getArgs()); 
       else 
        result = jp.proceed(); 
       break; 
      } catch (DataAccessResourceFailureException ex) { 
       if (retryCount < maxRetriesOnConnDrop) { 
        LOG.warn("Retrying...(retryCount=" + retryCount + ")"); 
        sleep(retryWaitInMillis); 
       } else { 
        throw ex; 
       } 
      } 
      retryCount++; 
     } while (retryCount <= maxRetriesOnConnDrop); 
     return result; 
    } 
} 
0

मैं इसी तरह की समस्या है। मैं पोस्टग्रेस 9.4 का उपयोग करता हूं। स्प्रिंग 4 और टॉमकैट 8. मैं स्प्रिंग कॉन्फ़िगरेशन

<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close"> 
    <property name="initialSize" value="10" /> 
    <property name="maxActive" value="25" /> 
    <property name="maxIdle" value="20" /> 
    <property name="minIdle" value="10" /> 
    <property name="driverClassName" value="org.postgresql.Driver" /> 
    <property name="url" value="${database.url}" /> 
    <property name="username" value="${database.username}" /> 
    <property name="password" value="${database.password}" /> 
    <property name="testOnBorrow" value="true" /> 
    <property name="validationQuery" value="SELECT 1" /> 
</bean> 

के साथ समस्या का समाधान करता हूं। यह अच्छा काम करता है!मैं बंद Postgres कर देते हैं, तो मैं इस तरह के प्रवेश है:

Caused by: java.net.ConnectException: Connection refused: connect 
    at java.net.DualStackPlainSocketImpl.connect0(Native Method) 

लेकिन जब मैं postgres शुरू करते हैं, सब कुछ ठीक है! यह दो पंक्ति डेटाबेस से पुन: कनेक्ट करने के लिए सब कुछ करती है:

<property name="testOnBorrow" value="true" /> 
<property name="validationQuery" value="SELECT 1" /> 
संबंधित मुद्दे