web项目为什么按装到tomcat服务器上过一个星期后就无法连接数据库了?

时间:2022-09-23 16:51:33
web项目为什么按装到tomcat服务器上过一个星期后就无法连接数据库了?重起tomcat服务器后就又可以使用了。
代码中数据库的连接每次使用后都关闭了。 [

8 个解决方案

#1


你那是数据库连接池是吧,数据库有个默认的时间间隔,如果过了那时间间隔没用,就会自动断掉的.
参数没有配置完全

#2


引用 1 楼 jack420124 的回复:
你那是数据库连接池是吧,数据库有个默认的时间间隔,如果过了那时间间隔没用,就会自动断掉的. 
参数没有配置完全 

有道理

#3


引用 1 楼 jack420124 的回复:
你那是数据库连接池是吧,数据库有个默认的时间间隔,如果过了那时间间隔没用,就会自动断掉的. 
参数没有配置完全 

1楼:你说的不是没有道理。这个项目已经发布到网上了。每天都有上百人登录。什么都正常。只是过一个来星期,就突然出现这种问题,在重新重起一下服务器也就好了。但总不能每次都要重起服务器吧。请指点。

#4


你这数据库连接池是老版本的dbcp.新的功能有这么个特点,如果数据库引擎与你pools 的connection 连接断开,
或你数据库引擎停止后又启动了,那这样池中的pools 会把断掉的connection 自动remove 掉的,
你换个新的版本dbcp ,后测试下,
    测试步骤如下: 你首先写个简单程序创建保证pools 的连接达到maxActive 数字,设个断点
后,停止数据库引擎,在用dabaseSource.getConection取下连接,看有没有提示connection 断开什么样的错误提示就行了

如果有什么问题你,可以联系我QQ:542995961

#5


也就是说,你换个新的dbcp 版本,也就没你那问题了

#6


我上面说得有点不对,因为dbcp 依赖容器,和单独在代码里面不一样的:
如果是在代码里面向下面这样用:
package db;


import java.io.Serializable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLData;
import java.sql.SQLException;
import java.sql.SQLInput;
import java.sql.SQLOutput;
import java.sql.Statement;
import org.apache.commons.dbcp.BasicDataSource;

public class MySQLConnectionManager 
{
private String url = "jdbc:mysql://localhost:3306/db_wis";
private String userName = "root";
private String password = "sa";
private BasicDataSource bds;
public MySQLConnectionManager()
{
bds = new BasicDataSource();
bds.setDriverClassName("org.gjt.mm.mysql.Driver");
    bds.setUrl(url);
    bds.setUsername(userName);
    bds.setPassword(password);
    bds.setMaxActive(30);
    bds.setDefaultAutoCommit(false);
    bds.setMaxWait(10000);
    bds.setValidationQuery("select 1");
    bds.setTestOnBorrow(true);
    bds.setTestOnReturn(true);
    bds.setTestWhileIdle(true);
          
}

void checkConnection()throws Exception
{
Connection  connection  = bds.getConnection();
System.out.println("connection  currentActive = " + bds.getNumActive());

Connection  connection1  = bds.getConnection();
System.out.println(" connection1  currentActive = " + bds.getNumActive());
Connection  connection2  = bds.getConnection();
System.out.println(" connection2  currentActive = " + bds.getNumActive());

System.out.println(connection.hashCode());
System.out.println(connection1.hashCode());
System.out.println(connection2.hashCode());


connection.close();

Connection aa = bds.getConnection();
System.out.println(aa.hashCode());
aa.close();
connection2.close();
connection1.close();
Thread.currentThread().sleep(1000*15);
Connection testconnection = bds.getConnection();
System.out.println(testconnection.hashCode() + ">>>> " + testconnection.isClosed() + bds.getNumActive());
Statement statement  = testconnection.createStatement();
ResultSet resultSet  = statement.executeQuery("select * from wis_admin_user");
while(resultSet.next())
{
System.out.println("resultSet.getInt(2) = " + resultSet.getString(2));
}
if(resultSet != null)
resultSet.close();
if(testconnection != null)
testconnection.close();
}

public static void main(String []args)
{
try
{
MySQLConnectionManager connectionManager  = new MySQLConnectionManager();
connectionManager.checkConnection();
}catch(Exception ex)
{
ex.printStackTrace();
}
}
}



的话,我上面说的是对的,断掉的物理连接会 pools 会自己remove 断掉的对象.

依赖tomcat 就不一样了:
配置数据库dbcp 
我测试过培植如下:
 <Resource name="jdbc/TestDB"
              auth="Container"
              type="javax.sql.DataSource" username="root" password="sa" maxActive = "3" maxIdle = "30" maxWait = "10000"
  testOnBorrow = "true" testOnReturn = "true" testWhileIdle = "true" 
  validationQuery = " select 1 " 
  driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/db_wis"/>
 
</Context>

web.xml
 <resource-ref>
  <res-ref-name>jdbc/TestDB</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
</resource-ref>

java 代码:


public static void show()
{
javax.sql.DataSource ds = null;
System.out.println(" -------------------  show()");
try{
Context ctx = new InitialContext();
 if(ctx == null)
 throw new Exception("no Context!");
  System.out.print("  >>>>> " + ctx.lookup("java:comp/env/jdbc/TestDB").getClass());
    ds =  (DataSource)ctx.lookup("java:comp/env/jdbc/TestDB");
 

 }catch(Exception e)
{
  System.out.println(e.getMessage());
  
  return;
}
 Connection testconnection = null;
 
 try{
 testconnection = ds.getConnection();
System.out.println(testconnection.hashCode() + ">>>> " + testconnection.isClosed() );
Statement statement  = testconnection.createStatement();
ResultSet resultSet  = statement.executeQuery("select * from wis_admin_user");
while(resultSet.next())
{
System.out.println("resultSet.getInt(2) = " + resultSet.getString(2));
}
if(resultSet != null)
resultSet.close();

 }catch(Exception ex)
 {
 ex.printStackTrace();
 
 }
 finally
 {
 try{
 if(testconnection != null)
 {
 if(!testconnection.isClosed())
 testconnection.close();
 }
 }catch(Exception ex){
 ex.printStackTrace();
 }
 }
}
测试的:
1:如果是: <Resource name="jdbc/TestDB"
              auth="Container"
              type="javax.sql.DataSource" username="root" password="sa" maxActive = "3" maxIdle = "30" maxWait = "10000"
    
  driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/db_wis"/>
 
</Context>
会出错,时间超过了mysql wait_timeout ,interactive_timeout(我设置的是5秒)连接断掉后,它的物理连接断掉了.
pools 里面的连接对象没删除.超过了3个死掉了.更本不行不通.
2:如果是
<Resource name="jdbc/TestDB"
              auth="Container"
              type="javax.sql.DataSource" username="root" password="sa" maxActive = "3" maxIdle = "30" maxWait = "10000"
    
  driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/db_wis?autoReconnect=true"/>

会出错,时间超过了mysql wait_timeout ,interactive_timeout(我设置的是5秒)连接断掉后,它的物理连接断掉了.
pools 里面的连接对象 会出现一次异常,tomcat 会自动去连接,如果在超过 5 秒没用,又会断开,如此下去.(这样的话
在写程序我门要做异常处理,在异常里重新取得连接,照样可以)

3:如果是
 <Resource name="jdbc/TestDB"
              auth="Container"
              type="javax.sql.DataSource" username="root" password="sa" maxActive = "3" maxIdle = "30" maxWait = "10000"
  testOnBorrow = "true" testOnReturn = "true" testWhileIdle = "true" 
  validationQuery = " select 1 " 
  driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/db_wis"/>
 
</Context>
是我们开发过程最好的选择:
如果连接取连接会检测物理连接是否断掉,如果断掉,就会在pools remove 断掉了的代理连接.不会挂掉的.(就会象第一种测试那样挂掉的 因为我们设置的maxActive = 3 活动对象最大数是3 ,但它的物理连接都断掉了)
注意 validationQuery 是一定要的;(如果没有,设置testOnBorrow,testOnReturn,testWhileIdle 无效的)


好了这是我做天下午的总结:也算是动了我一翻脑筋了啊:也算把我心得跟大家分享下,希望对大家开发有所帮助.
如果我总结的是对的.帮我顶下,呵呵.如果分析有漏洞,有错误望大家指点
我的邮箱地址:wxp03@163.com ,QQ:542995961




#7


是我们开发过程最好的选择:
如果连接取连接会检测物理连接是否断掉,如果断掉,就会在pools remove 断掉了的代理连接.不会挂掉的.(就会象第一种测试那样挂掉的 因为我们设置的maxActive = 3 活动对象最大数是3 ,但它的物理连接都断掉了)
注意 validationQuery 是一定要的;(如果没有,设置testOnBorrow,testOnReturn,testWhileIdle 无效的)

#8


该回复于2010-12-21 10:12:30被版主删除

#1


你那是数据库连接池是吧,数据库有个默认的时间间隔,如果过了那时间间隔没用,就会自动断掉的.
参数没有配置完全

#2


引用 1 楼 jack420124 的回复:
你那是数据库连接池是吧,数据库有个默认的时间间隔,如果过了那时间间隔没用,就会自动断掉的. 
参数没有配置完全 

有道理

#3


引用 1 楼 jack420124 的回复:
你那是数据库连接池是吧,数据库有个默认的时间间隔,如果过了那时间间隔没用,就会自动断掉的. 
参数没有配置完全 

1楼:你说的不是没有道理。这个项目已经发布到网上了。每天都有上百人登录。什么都正常。只是过一个来星期,就突然出现这种问题,在重新重起一下服务器也就好了。但总不能每次都要重起服务器吧。请指点。

#4


你这数据库连接池是老版本的dbcp.新的功能有这么个特点,如果数据库引擎与你pools 的connection 连接断开,
或你数据库引擎停止后又启动了,那这样池中的pools 会把断掉的connection 自动remove 掉的,
你换个新的版本dbcp ,后测试下,
    测试步骤如下: 你首先写个简单程序创建保证pools 的连接达到maxActive 数字,设个断点
后,停止数据库引擎,在用dabaseSource.getConection取下连接,看有没有提示connection 断开什么样的错误提示就行了

如果有什么问题你,可以联系我QQ:542995961

#5


也就是说,你换个新的dbcp 版本,也就没你那问题了

#6


我上面说得有点不对,因为dbcp 依赖容器,和单独在代码里面不一样的:
如果是在代码里面向下面这样用:
package db;


import java.io.Serializable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLData;
import java.sql.SQLException;
import java.sql.SQLInput;
import java.sql.SQLOutput;
import java.sql.Statement;
import org.apache.commons.dbcp.BasicDataSource;

public class MySQLConnectionManager 
{
private String url = "jdbc:mysql://localhost:3306/db_wis";
private String userName = "root";
private String password = "sa";
private BasicDataSource bds;
public MySQLConnectionManager()
{
bds = new BasicDataSource();
bds.setDriverClassName("org.gjt.mm.mysql.Driver");
    bds.setUrl(url);
    bds.setUsername(userName);
    bds.setPassword(password);
    bds.setMaxActive(30);
    bds.setDefaultAutoCommit(false);
    bds.setMaxWait(10000);
    bds.setValidationQuery("select 1");
    bds.setTestOnBorrow(true);
    bds.setTestOnReturn(true);
    bds.setTestWhileIdle(true);
          
}

void checkConnection()throws Exception
{
Connection  connection  = bds.getConnection();
System.out.println("connection  currentActive = " + bds.getNumActive());

Connection  connection1  = bds.getConnection();
System.out.println(" connection1  currentActive = " + bds.getNumActive());
Connection  connection2  = bds.getConnection();
System.out.println(" connection2  currentActive = " + bds.getNumActive());

System.out.println(connection.hashCode());
System.out.println(connection1.hashCode());
System.out.println(connection2.hashCode());


connection.close();

Connection aa = bds.getConnection();
System.out.println(aa.hashCode());
aa.close();
connection2.close();
connection1.close();
Thread.currentThread().sleep(1000*15);
Connection testconnection = bds.getConnection();
System.out.println(testconnection.hashCode() + ">>>> " + testconnection.isClosed() + bds.getNumActive());
Statement statement  = testconnection.createStatement();
ResultSet resultSet  = statement.executeQuery("select * from wis_admin_user");
while(resultSet.next())
{
System.out.println("resultSet.getInt(2) = " + resultSet.getString(2));
}
if(resultSet != null)
resultSet.close();
if(testconnection != null)
testconnection.close();
}

public static void main(String []args)
{
try
{
MySQLConnectionManager connectionManager  = new MySQLConnectionManager();
connectionManager.checkConnection();
}catch(Exception ex)
{
ex.printStackTrace();
}
}
}



的话,我上面说的是对的,断掉的物理连接会 pools 会自己remove 断掉的对象.

依赖tomcat 就不一样了:
配置数据库dbcp 
我测试过培植如下:
 <Resource name="jdbc/TestDB"
              auth="Container"
              type="javax.sql.DataSource" username="root" password="sa" maxActive = "3" maxIdle = "30" maxWait = "10000"
  testOnBorrow = "true" testOnReturn = "true" testWhileIdle = "true" 
  validationQuery = " select 1 " 
  driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/db_wis"/>
 
</Context>

web.xml
 <resource-ref>
  <res-ref-name>jdbc/TestDB</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
</resource-ref>

java 代码:


public static void show()
{
javax.sql.DataSource ds = null;
System.out.println(" -------------------  show()");
try{
Context ctx = new InitialContext();
 if(ctx == null)
 throw new Exception("no Context!");
  System.out.print("  >>>>> " + ctx.lookup("java:comp/env/jdbc/TestDB").getClass());
    ds =  (DataSource)ctx.lookup("java:comp/env/jdbc/TestDB");
 

 }catch(Exception e)
{
  System.out.println(e.getMessage());
  
  return;
}
 Connection testconnection = null;
 
 try{
 testconnection = ds.getConnection();
System.out.println(testconnection.hashCode() + ">>>> " + testconnection.isClosed() );
Statement statement  = testconnection.createStatement();
ResultSet resultSet  = statement.executeQuery("select * from wis_admin_user");
while(resultSet.next())
{
System.out.println("resultSet.getInt(2) = " + resultSet.getString(2));
}
if(resultSet != null)
resultSet.close();

 }catch(Exception ex)
 {
 ex.printStackTrace();
 
 }
 finally
 {
 try{
 if(testconnection != null)
 {
 if(!testconnection.isClosed())
 testconnection.close();
 }
 }catch(Exception ex){
 ex.printStackTrace();
 }
 }
}
测试的:
1:如果是: <Resource name="jdbc/TestDB"
              auth="Container"
              type="javax.sql.DataSource" username="root" password="sa" maxActive = "3" maxIdle = "30" maxWait = "10000"
    
  driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/db_wis"/>
 
</Context>
会出错,时间超过了mysql wait_timeout ,interactive_timeout(我设置的是5秒)连接断掉后,它的物理连接断掉了.
pools 里面的连接对象没删除.超过了3个死掉了.更本不行不通.
2:如果是
<Resource name="jdbc/TestDB"
              auth="Container"
              type="javax.sql.DataSource" username="root" password="sa" maxActive = "3" maxIdle = "30" maxWait = "10000"
    
  driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/db_wis?autoReconnect=true"/>

会出错,时间超过了mysql wait_timeout ,interactive_timeout(我设置的是5秒)连接断掉后,它的物理连接断掉了.
pools 里面的连接对象 会出现一次异常,tomcat 会自动去连接,如果在超过 5 秒没用,又会断开,如此下去.(这样的话
在写程序我门要做异常处理,在异常里重新取得连接,照样可以)

3:如果是
 <Resource name="jdbc/TestDB"
              auth="Container"
              type="javax.sql.DataSource" username="root" password="sa" maxActive = "3" maxIdle = "30" maxWait = "10000"
  testOnBorrow = "true" testOnReturn = "true" testWhileIdle = "true" 
  validationQuery = " select 1 " 
  driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/db_wis"/>
 
</Context>
是我们开发过程最好的选择:
如果连接取连接会检测物理连接是否断掉,如果断掉,就会在pools remove 断掉了的代理连接.不会挂掉的.(就会象第一种测试那样挂掉的 因为我们设置的maxActive = 3 活动对象最大数是3 ,但它的物理连接都断掉了)
注意 validationQuery 是一定要的;(如果没有,设置testOnBorrow,testOnReturn,testWhileIdle 无效的)


好了这是我做天下午的总结:也算是动了我一翻脑筋了啊:也算把我心得跟大家分享下,希望对大家开发有所帮助.
如果我总结的是对的.帮我顶下,呵呵.如果分析有漏洞,有错误望大家指点
我的邮箱地址:wxp03@163.com ,QQ:542995961




#7


是我们开发过程最好的选择:
如果连接取连接会检测物理连接是否断掉,如果断掉,就会在pools remove 断掉了的代理连接.不会挂掉的.(就会象第一种测试那样挂掉的 因为我们设置的maxActive = 3 活动对象最大数是3 ,但它的物理连接都断掉了)
注意 validationQuery 是一定要的;(如果没有,设置testOnBorrow,testOnReturn,testWhileIdle 无效的)

#8


该回复于2010-12-21 10:12:30被版主删除