2010-01-23 168 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会验证你的每一个连接。

相关问题