数据库轮询器:MySQLNonTransientConnectionException:连接太多

时间:2014-05-09 12:23:24

标签: jdbc

我编写了一个WebService,负责每隔3秒轮询一次DB并发送最新数据

不幸的是,我在一段时间后在我的控制台中收到此异常。

Connection Failed! Check output console
com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: Too many connections
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:921)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2985)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:885)
        at com.mysql.jdbc.MysqlIO.secureAuth411(MysqlIO.java:3421)
        at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1247)
        at com.mysql.jdbc.Connection.createNewIO(Connection.java:2775)
        at com.mysql.jdbc.Connection.<init>(Connection.java:1555)
        at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
        at java.sql.DriverManager.getConnection(DriverManager.java:579)
        at java.sql.DriverManager.getConnection(DriverManager.java:221)
        at com.serviceees.DBPollerService.getUpdates(DBPollerService.java:47)
        at sun.reflect.GeneratedMethodAccessor51.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:168)
        at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:70)
        at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:279)
        at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:86)
        at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:136)
        at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:74)
        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1357)
        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1289)
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1239)
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1229)
        at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:420)
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:497)
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:684)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:291)
        at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:877)
        at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:594)
        at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1675)
        at java.lang.Thread.run(Thread.java:722)

这是我的计划

package com.serviceees;


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import com.google.gson.Gson;

import dto.Orders;

@Path("/updates")
public class DBPollerService {
    @GET
    @Produces("application/json")
    public String getUpdates() {
        String clientResponse = "Error";
        ArrayList<Orders> newOrdersList = new ArrayList<Orders>();  
        Gson gson = new Gson();
        try {

            try {
                Class.forName("com.mysql.jdbc.Driver");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            Connection connection = null;
            PreparedStatement preparedStatement = null;
            String selectSQL = "SELECT *\r\n" + 
            "FROM Orders\r\n" + 
            "INNER JOIN (\r\n" + 
            "    SELECT id, updated_at AS modified from Orders\r\n" + 
            "    UNION\r\n" + 
            "    SELECT id, created_at from Orders \r\n" + 
            ") AS whatever ON whatever.id = Orders.id\r\n" + 
            "ORDER BY whatever.modified DESC;\r\n" + 
            "";
            try {
                connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "", "");
                preparedStatement = connection.prepareStatement(selectSQL);
                while (true) {

                    try {


                        ResultSet rs = preparedStatement.executeQuery(selectSQL);
                        while (rs.next()) {
                            Orders order = new Orders();
                            order.setId(rs.getInt(1));
                            order.setVendorName(rs.getString(2));
                            order.setItem(rs.getString(3));
                            newOrdersList.add(order);
                        }
                        clientResponse =    "jsonCallback(["+gson.toJson(newOrdersList)+"])";
                        Thread.sleep(3000);
                    //  System.out.println("clientResponse"+clientResponse);
                        return clientResponse;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            } catch (SQLException e) {
            //  System.out.println("Connection Failed! Check output console");
                e.printStackTrace();

            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    //  clientResponse =    gson.toJson(newOrdersList); 

        return clientResponse;
    }

}

2 个答案:

答案 0 :(得分:0)

注意:这已经多次answered了。

您需要关闭jdbc ConnectionPreparedStatementResultSet个对象。最简单的方法是将finally块添加到try / catch块的末尾,包含对getConnectionprepareStatement的调用:

try {
    connection = DriverManager.getConnection(...)
    ...
} catch ...
...
} finally {
    // Each of these needs wrapped in a try / catch block
    if(resultSet != null) { resultSet.close() }
    if(preparedStatement != null) { preparedStatement.close() }
    if(connection != null) { connection.close() }
}

使用JDBC时,我通常会编写辅助方法来处理结束任务。通过将它们放在finally中,您可以确保它们始终被执行(无论您是获得异常还是从try块中返回。

答案 1 :(得分:0)

您可以使用 try资源功能来处理关闭连接

try(Connection con=DriverManager.getConnection()){
//sql queries
}
catch(SQLException ex){
//error handling code
}