2010-01-23 177 views
4

關閉的連接 - 爲什麼?Jboss的數據源恢復後,數據庫連接池還是重新啓動

servlet-

public class Index extends HttpServlet { 

    TimeZoneService timeZoneService; 

    public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException { 
     WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); 
     timeZoneService = (TimeZoneService) ctx.getBean("timeZoneService"); 
     timeZoneService.loadAllTimeZones(); 
     System.out.println("Done"); 
    } 
} 

public interface TimeZoneService { 
    void loadAllTimeZones(); 
} 

public class TimeZoneServiceImpl implements TimeZoneService { 

    private TimeZoneDao tzDao; 
    private Map<Long, String> tzOid2JavaName = new HashMap<Long, String>(); 

    public void loadAllTimeZones() { 
     List<TimeZone> timeZones = tzDao.findAllTimeZones(); 
     for (TimeZone tz : timeZones) { 
      tzOid2JavaName.put(tz.getOid(), tz.getJavaName()); 
     } 
    } 

    public void setTzDao(TimeZoneDao tzDao) { 
     this.tzDao = tzDao; 
    } 
} 

public interface TimeZoneDao { 
    List<TimeZone> findAllTimeZones() throws DataAccessException; 
} 

public class TimeZoneDaoImpl extends JdbcDaoSupport implements TimeZoneDao { 

    public List<TimeZone> findAllTimeZones() throws DataAccessException 
    { 
     StringBuffer sql = new StringBuffer(); 
     sql.append("SELECT TZ.OID, TZ.JAVA_NAME FROM TIME_ZONE TZ"); 
     List<TimeZone> timeZones = getJdbcTemplate().query(sql.toString(), new RowMapper() { 
      public Object mapRow(ResultSet rs, int i) throws SQLException { 
       TimeZone tz = new TimeZone(); 
       tz.setOid(rs.getLong("OID")); 
       tz.setJavaName(rs.getString("JAVA_NAME")); 
       return tz; 
      } 
     }); 

     return timeZones; 
    } 
} 

public class TimeZone { 
    private Long oid; 
    private String javaName; 

    public Long getOid() { 
     return this.oid; 
    } 

    public void setOid(Long oid) { 
     this.oid = oid; 
    } 

    public String getJavaName() { 
     return this.javaName; 
    } 

    public void setJavaName(String javaName) { 
     this.javaName = javaName; 
    } 
} 

彈簧-config.xml中

<beans> 

    <jee:jndi-lookup id="dataSource" jndi-name="java:/OracleDS"/> 

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
     <property name="dataSource" ref="dataSource"/> 
    </bean> 

    <bean id="timeZoneDao" class="dao.impl.TimeZoneDaoImpl"> 
     <property name="dataSource" ref="dataSource"/> 
    </bean> 

    <bean id="timeZoneService" class="logic.impl.TimeZoneServiceImpl"> 
     <property name="tzDao" ref="timeZoneDao"/> 
    </bean> 

</beans> 

的web.xml

<web-app> 

    <display-name>Spring</display-name> 

    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value> 
      WEB-INF/spring-config.xml,classpath*:/META-INF/spring-config.xml</param-value> 
    </context-param> 

    <listener> 
     <listener-class> 
      org.springframework.web.context.ContextLoaderListener 
     </listener-class> 
    </listener> 

    <servlet> 
     <servlet-name>index</servlet-name> 
     <display-name>Index page</display-name> 
     <description>Landing page</description> 
     <servlet-class>servlet.Index</servlet-class> 
    </servlet> 

    <servlet-mapping> 
     <servlet-name>index</servlet-name> 
     <url-pattern>/index</url-pattern> 
    </servlet-mapping> 

    <!-- Session Timeout (in minutes) --> 
    <session-config> 
     <session-timeout>60</session-timeout> 
    </session-config> 
</web-app> 

的MySQL-ds.xml中

<datasources> 
    <local-tx-datasource> 
     <jndi-name>OracleDS</jndi-name> 
     <connection-url>jdbc:mysql://localhost:3306/spring</connection-url> 
     <driver-class>com.mysql.jdbc.Driver</driver-class> 
     <user-name>spring_test</user-name> 
     <password>spring_test13</password> 
     <min-pool-size>1</min-pool-size> 
     <max-pool-size>5</max-pool-size> 
     <idle-timeout-minutes>2</idle-timeout-minutes> 
    </local-tx-datasource> 
</datasources> 
+0

的MySQL-ds.xml中 <本地-TX-數據源> OracleDS <連接-URL> JDBC:MySQL的://本地主機:3306 /彈簧 <驅動程序 - 類> com.mysql.jdbc.Driver spring_test spring_test13 <分鐘池大小> 1 5 2 Prasanth 2010-01-23 00:14:43

回答

2

這是使用連接池時遇到的常見問題。當應用程序借用池中的連接,應池本身的「測試」的連接,以確保它仍然是有效的,還是應該離開這個由應用程序?

如果池測試連接,這不可避免地涉及發送下來的東西連接到數據庫服務器(通常是某種形式的基本的SELECT)。在高流量系統上,這非常浪費,並且可能給數據庫服務器增加相當大的壓力。

在低流量的網站,但是,你的數據庫可以處理額外的負荷,你可以配置你的數據源,使JBoss的驗證它傳遞給你的應用程序之前的連接。如果連接失效,JBoss會將其從池中移除並獲得一個新的連接,以便在數據庫重新啓動後存活。

所有,添加到您的mysql-ds.xml文件:

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

你必須自己挑查詢,確保它不貴,因爲它會運行一個很多

JBoss documentation wiki,看看如何修改這些數據源文件。

+0

是的。還有另一個配置可以看到Jboss在返回連接之前做了些什麼。有效連接檢查器類名應該是發佈SQL的'更好'。既然你提到應用程序應該能夠處理這種情況,我想知道Hibernate/Spring框架是否能爲我們做到這一點?由於關閉連接例外附帶所有數據庫的標準代碼。 – Prasanth 2010-01-24 17:23:35

+0

不,Spring或Hibernate都不能處理這個問題。如果您要重新啓動數據庫服務器,則可以使用連接檢查程序,也可以重新啓動應用服務器。哦,'valid-connection-checker-class-name'也發佈SQL,它只是在封面下面做的。沒什麼區別。 – skaffman 2010-01-24 18:04:37

+0

@skaffman除了使用tns ping的 org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker外,這裏提到http://stackoverflow.com/a/145889/274414 – 2013-11-01 18:17:07

7

確定。希望以下是有用的人:-)

有一個數據源配置設置 - exception-sorter-class-name

根據到JBoss這是用來a class that looks at vendor specific messages to determine whether sql errors are fatal and thus the connection should be destroyed. If none specified, no errors will be treated as fatal.

如果使用Oracle數據庫這個配置設置爲org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter爲。這個類有所有需要被視爲致命的錯誤代碼,因此連接需要被銷燬。

在Jboss 4中,不包括錯誤代碼17002(連接重置)& & 17008(連接關閉)。它們被添加到Jboss 5中。因此,如果您使用的是Jboss 4並想知道爲什麼連接沒有被恢復,請嘗試添加缺少的代碼。

1

這裏是的JBoss 7.1+與Oracle數據庫連接validaton配置:

<validation> 
    <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.vendor.OracleValidConnectionChecker"/> 
    <check-valid-connection-sql>select 1 from dual</check-valid-connection-sql> 
    <stale-connection-checker class-name="org.jboss.jca.adapters.jdbc.vendor.OracleStaleConnectionChecker"/> 
    <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter"/> 
</validation> 

現在JBoss會驗證你的每一個連接。

相關問題