org.apache.tomcat.dbcp.dbcp.SQLNestedException:无法获取连接,池错误等待空闲对象超时
我使用的是Tomcat 7、MySql Workbench 5.2.27和JSF 2.0,这个异常来自我的web pageTrip Record.xhtml的ManagedBeanTripTableBean.java。在浏览其他网页后,每当我单击以转到Trip Record.xhtml时,它就会出现。请原谅我可怕的密码 TripTableBean.java } 更新2:org.apache.tomcat.dbcp.dbcp.SQLNestedException:无法获取连接,池错误等待空闲对象超时,exception,jakarta-ee,jsf-2,tomcat7,mysql-workbench,Exception,Jakarta Ee,Jsf 2,Tomcat7,Mysql Workbench,我使用的是Tomcat 7、MySql Workbench 5.2.27和JSF 2.0,这个异常来自我的web pageTrip Record.xhtml的ManagedBeanTripTableBean.java。在浏览其他网页后,每当我单击以转到Trip Record.xhtml时,它就会出现。请原谅我可怕的密码 TripTableBean.java } 更新2: 当ManagedBeanTripTableBean.java的作用域是ViewScope时会发生此异常,当我将其更改为Sess
当ManagedBeanTripTableBean.java的作用域是ViewScope时会发生此异常,当我将其更改为SessionScoped时不会发生此异常。但是,如果是会话范围,我需要找到一种方法,在每次访问此网页时终止会话并重新创建一个新会话。如果不是,则此网页上的dataTable不会从数据库加载更新的更改。您有什么连接池设置可以在DBController中发布什么? 提示:db.terminate应该位于finally{}块中,可能是因为您在异常情况下丢失了连接 更新: 发布一些可能会对您有所帮助的修改,但为了维护起见,一定要清理代码。查找已进行更改的注释
public class DBController {
private DataSource ds;
private Connection con;// NEW CHANGE
public void setUp() throws NamingException{
//connect to database
Context ctx = new InitialContext();
ds = (DataSource)ctx.lookup("java:comp/env/jdbc/it2299");
con = ds.getConnection(); // NEW CHANGE
}
public ResultSet readRequest(String dbQuery){
ResultSet rs=null;
try{
//REMOVED CODE FROM HERE
Statement stmt = con.createStatement();
rs = stmt.executeQuery(dbQuery);
}
catch(Exception e){e.printStackTrace();}
return rs;
}
public int updateRequest(String dbQuery){
int count=0;
try{
//REMOVED CODE FROM HERE
Statement stmt = con.createStatement();
count=stmt.executeUpdate(dbQuery);
}
catch(Exception e){e.printStackTrace();}
return count;
}
public void terminate(){
try {con.close();}
catch(Exception e){e.printStackTrace();}
}
}
除此之外,我无法改进代码,但我建议大家看看@BalusC建议的一些网上最佳实践。
记住:完成后关闭连接对象。您的连接池设置是什么?您可以在DBController中发布什么? 提示:db.terminate应该位于finally{}块中,可能是因为您在异常情况下丢失了连接 更新: 发布一些可能会对您有所帮助的修改,但为了维护起见,一定要清理代码。查找已进行更改的注释
public class DBController {
private DataSource ds;
private Connection con;// NEW CHANGE
public void setUp() throws NamingException{
//connect to database
Context ctx = new InitialContext();
ds = (DataSource)ctx.lookup("java:comp/env/jdbc/it2299");
con = ds.getConnection(); // NEW CHANGE
}
public ResultSet readRequest(String dbQuery){
ResultSet rs=null;
try{
//REMOVED CODE FROM HERE
Statement stmt = con.createStatement();
rs = stmt.executeQuery(dbQuery);
}
catch(Exception e){e.printStackTrace();}
return rs;
}
public int updateRequest(String dbQuery){
int count=0;
try{
//REMOVED CODE FROM HERE
Statement stmt = con.createStatement();
count=stmt.executeUpdate(dbQuery);
}
catch(Exception e){e.printStackTrace();}
return count;
}
public void terminate(){
try {con.close();}
catch(Exception e){e.printStackTrace();}
}
}
除此之外,我无法改进代码,但我建议大家看看@BalusC建议的一些网上最佳实践。
请记住:完成后关闭连接对象。正如您所暗示的,您的代码非常糟糕。您需要确保在try-finally块中在尽可能短的范围内获取并关闭所有JDBC资源。重写代码,使其遵循以下标准JDBC习惯用法:
public List<Entity> list() throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
List<Entity> entities = new ArrayList<Entity>();
try {
connection = Database.getConnection();
statement = connection.prepareStatement("SELECT id, foo, bar FROM entity");
resultSet = statement.executeQuery();
while (resultSet.next()) {
Entity entity = new Entity();
entity.setId(resultSet.getLong("id"));
entity.setFoo(resultSet.getString("foo"));
entity.setBar(resultSet.getString("bar"));
entities.add(entity);
}
} finally {
if (resultSet != null) try { resultSet.close(); } catch (SQLException ignore) {}
if (statement != null) try { statement.close(); } catch (SQLException ignore) {}
if (connection != null) try { connection.close(); } catch (SQLException ignore) {}
}
return entities;
}
另见:
正如你自己暗示的,你的代码很糟糕。您需要确保在try-finally块中在尽可能短的范围内获取并关闭所有JDBC资源。重写代码,使其遵循以下标准JDBC习惯用法:
public List<Entity> list() throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
List<Entity> entities = new ArrayList<Entity>();
try {
connection = Database.getConnection();
statement = connection.prepareStatement("SELECT id, foo, bar FROM entity");
resultSet = statement.executeQuery();
while (resultSet.next()) {
Entity entity = new Entity();
entity.setId(resultSet.getLong("id"));
entity.setFoo(resultSet.getString("foo"));
entity.setBar(resultSet.getString("bar"));
entities.add(entity);
}
} finally {
if (resultSet != null) try { resultSet.close(); } catch (SQLException ignore) {}
if (statement != null) try { statement.close(); } catch (SQLException ignore) {}
if (connection != null) try { connection.close(); } catch (SQLException ignore) {}
}
return entities;
}
另见:
谢谢你的帮助,我将尝试添加最后{}块。我已经在帖子中添加了我的DBController。更新:异常仍然发生。我尝试用另一个网页交替打开此网页,当我第6次单击转到此网页时出现异常。最后{}我的意思是通过应用程序而不仅仅是上面的代码:。我还注意到您的readRequest方法打开了一个新的连接,它在循环中使用,您可以使用相同的连接来创建语句,这样它也可能在事务中有所帮助。您可能需要一些代码中的where。嗯,使用相同的连接?您的意思是对所有dbQuery使用相同的结果集?或者为每个结果集创建一个新的DBController?我迷路了=\这种方法仍然很糟糕。您需要重写更多的代码。感谢您的帮助,我将尝试添加finally{}块。我已经在帖子中添加了我的DBController。更新:异常仍然发生。我尝试用另一个网页交替打开此网页,当我第6次单击转到此网页时出现异常。最后{}我的意思是通过应用程序而不仅仅是上面的代码:。我还注意到您的readRequest方法打开了一个新的连接,它在循环中使用,您可以使用相同的连接来创建语句,这样它也可能在事务中有所帮助。您可能需要一些代码中的where。嗯,使用相同的连接?您的意思是对所有dbQuery使用相同的结果集?或者为每个结果集创建一个新的DBController?我迷路了=\这种方法仍然很糟糕。你需要重写更多的代码。也谢谢你的帮助,我目前正试图遵循上述格式。呃,我可以知道那个数据库类中有什么吗?第7行导入=\不可用,在仍然执行while循环第一次查询的情况下,如何执行while循环第二次查询?关于数据库类,请参阅链接以获取示例。它应该只创建并返回连接,而不是将该连接作为该类的实例变量!。至于第二个查询,请学习SQL JOIN子句,这样您只会得到一个查询,它会精确地返回您所需的数据。也感谢您的帮助,我目前正在尝试使用上述格式。呃,我可以知道那个数据库类中有什么吗?第7行导入=\不可用,在仍然执行while循环第一次查询的情况下,如何执行while循环第二次查询?关于数据库类,请参阅链接以获取示例。它应该只创建并返回连接,而不是将该连接作为该类的实例变量!。至于第二个查询,请学习SQL JOIN子句,以便最终得到on ly 1查询,它精确地返回您需要的数据。
public List<Entity> list() throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
List<Entity> entities = new ArrayList<Entity>();
try {
connection = Database.getConnection();
statement = connection.prepareStatement("SELECT id, foo, bar FROM entity");
resultSet = statement.executeQuery();
while (resultSet.next()) {
Entity entity = new Entity();
entity.setId(resultSet.getLong("id"));
entity.setFoo(resultSet.getString("foo"));
entity.setBar(resultSet.getString("bar"));
entities.add(entity);
}
} finally {
if (resultSet != null) try { resultSet.close(); } catch (SQLException ignore) {}
if (statement != null) try { statement.close(); } catch (SQLException ignore) {}
if (connection != null) try { connection.close(); } catch (SQLException ignore) {}
}
return entities;
}