Java 数据库重新启动后恢复Jboss数据源
已关闭的连接仍在连接池中-为什么 servlet-Java 数据库重新启动后恢复Jboss数据源,java,jboss,datasource,Java,Jboss,Datasource,已关闭的连接仍在连接池中-为什么 servlet- public class Index extends HttpServlet { TimeZoneService timeZoneService; public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException { WebApplicationContext ctx = WebApplicat
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;
}
}
公共类索引扩展了HttpServlet{
时区服务时区服务;
public void doGet(HttpServletRequest-req,HttpServletResponse-res)抛出ServletException{
WebApplicationContext ctx=WebApplicationContextils.getRequiredWebApplicationContext(getServletContext());
timeZoneService=(timeZoneService)ctx.getBean(“timeZoneService”);
timeZoneService.loadAllTimeZones();
系统输出打印项次(“完成”);
}
}
公共接口时区服务{
void loadAllTimeZones();
}
公共类TimeZoneServiceImpl实现TimeZoneService{
私人时区dao tzDao;
私有映射tzOid2JavaName=newHashMap();
public void loadAllTimeZones(){
List timeZones=tzDao.findAllTimeZones();
用于(时区tz:时区){
tzOid2JavaName.put(tz.getOid(),tz.getJavaName());
}
}
公共无效setTzDao(时区dao tzDao){
this.tzDao=tzDao;
}
}
公共接口时区{
List findAllTimeZones()抛出DataAccessException;
}
公共类TimeZoneDaoImpl扩展JDBCDAO支持实现TimeZoneDao{
公共列表findAllTimeZones()引发DataAccessException
{
StringBuffer sql=新的StringBuffer();
append(“从时区TZ中选择TZ.OID、TZ.JAVA_名称”);
List timeZones=getJdbcTemplate().query(sql.toString(),new RowMapper()){
公共对象映射行(ResultSet rs,int i)引发SQLException{
时区tz=新时区();
z.setOid(rs.getLong(“OID”);
setJavaName(rs.getString(“JAVA_NAME”));
返回tz;
}
});
返回时区;
}
}
公共类时区{
私人长骨;
私有字符串javaName;
公共长getOid(){
返回此.oid;
}
公共void setOid(长oid){
this.oid=oid;
}
公共字符串getJavaName(){
返回this.javaName;
}
public void setJavaName(字符串javaName){
this.javaName=javaName;
}
}
spring-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>
春天
上下文配置位置
WEB-INF/spring-config.xml,classpath*:/META-INF/spring-config.xml
org.springframework.web.context.ContextLoaderListener
指数
索引页
登录页
servlet.Index
指数
/索引
60
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>
神谕
jdbc:mysql://localhost:3306/spring
com.mysql.jdbc.Driver
弹簧试验
春季考试13
1.
5.
2.
这是使用连接池时常见的问题。当应用程序从池借用连接时,池本身是否应该“测试”连接以确保其仍然有效,还是应该让应用程序自行决定
如果池测试连接,这不可避免地涉及到将连接中的某些内容发送到数据库服务器(通常是某种基本选择)。在高流量系统上,这是非常浪费的,并且会给数据库服务器增加相当大的压力
不过,在低流量站点上,您的数据库可以处理额外的负载,您可以配置数据源,使JBoss在将连接传递给应用程序之前验证连接。如果连接已断开,JBoss将从池中删除它并获得一个新的连接,以便在数据库重新启动后仍能生存
如果有,请将此添加到您的mysql ds.xml
文件中:
<check-valid-connection-sql>select 1 from mytable</check-valid-connection-sql>
从mytable中选择1
您必须自己选择查询,确保它不是一个昂贵的查询,因为它会运行很多次
请参阅以查看如何修改这些数据源文件。确定。希望以下内容对某人有用:-) 有一个数据源配置设置-
异常分类器类名
根据Jboss的说法,这用于一个类,该类查看特定于供应商的消息,以确定sql错误是否是致命的,因此应该销毁连接。如果未指定任何错误,则不会将任何错误视为致命错误。
如果使用Oracle数据库此配置设置为org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter
。此类包含所有需要视为致命的错误代码,因此需要销毁连接
在JBoss4中,错误代码17002(连接重置)和17008(连接关闭)不包括在内。它们被添加到JBoss5中。因此,如果您正在使用Jboss 4,并且想知道为什么没有恢复连接,请尝试添加缺少的代码。以下是针对Jboss 7.1+的oracle DB的连接验证配置:
从双重选择中选择1
现在Jboss将验证您的每个连接。mysql-ds.xml OracleDS jdbc:mysql://localhost:3306/spring com.mysql.jdbc.Driver spring\u test spring\u test13 1 5 2是。还有另外一个配置,可以看到Jboss在返回连接之前做了一些事情。有效的连接检查器类名应该比发出SQL的类名“更好”。既然您提到应用程序应该能够处理这种情况,我想知道Hibernate/Spring框架是否能为我们做到这一点?因为所有数据库的标准代码都会出现关闭连接异常。不,Spring和Hibernate都不能更好地处理这个问题。如果要重新启动数据库服务器,请使用连接检查器,或者重新启动appserver。哦,而且
有效的连接检查器类名
也会发出SQL,它只是在幕后进行。这是不可能的
<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>