MYSQL 尽管正确关闭资源,但获取数据的连接过多
MYSQL Getting Data too many connections in-spite of closing resources properly
我正在使用 mysql 5.0,我经常收到数据太多连接错误,我确信我正在关闭我的 finally 块中的所有连接
这是我的 class 用于获取数据库连接
public class DBConnection {
final static Logger logger = Logger.getLogger(DBConnection.class);
private static DataSource dataSource;
static {
try {
dataSource = (DataSource) new InitialContext().lookup("java:/comp/env/jdbc/REDEX");
} catch (NamingException e) {
logger.error("NamingException Occured" , e);
e.printStackTrace();
try {
// throw new Exception("'jndifordbconc' not found in JNDI",e);
} catch (Exception e1) {
//logger.error("Exception Occured" , e1);
logger.error("NamingException Occured" , e1);
e1.printStackTrace();
}
}
}
public static Connection getDBConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
logger.error("Exception Occured Under getDBConnection" , e);
return null;
}
}
public static void close(Connection con)
{
if (con != null)
{
try
{
con.close();
}
catch (SQLException e)
{
logger.error("Exception Occured inside close " , e);
}
}
}
public static void close(Statement stmt, ResultSet rs)
{
if (rs != null)
{
try
{
rs.close();
}
catch (SQLException e)
{
logger.error("Exception Occured while closing resultset " , e);
}
}
if (stmt != null)
{
try
{
stmt.close();
}
catch (SQLException e)
{
logger.error("Exception Occured while closing statement " , e);
}
}
}
}
连接池设置
<ResourceLink name="jdbc/REDEX"
global="jdbc/REDEX"
type="javax.sql.DataSource" />
<Resource name="jdbc/REDEX"
global="jdbc/REDEX"
type="javax.sql.DataSource"
auth="Container"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/REDEX?allowMultiQueries=true"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
username="root"
password="xxxxx@123"
initialSize="100"
maxActive="100"
maxIdle="20"
minIdle="10"
suspectTimeout="60"
timeBetweenEvictionRunsMillis="30000"
minEvictableIdleTimeMillis="60000"
validationQuery="SELECT 1"
validationInterval="34000"
testOnBorrow="true"
removeAbandoned="true"
removeAbandonedTimeout="55"
/>
示例 java class 我如何使用连接和关闭
public class GetBrands {
final static Logger logger = Logger.getLogger(GetBrands.class);
@GET
@Consumes("application/text")
@Produces("application/json")
public String getAllBrands() throws JSONException
{
logger.error("the GetBrands got called");
Connection dbConnection = null;
PreparedStatement getAllBrandsPst = null ;
ResultSet getAllBrandsResltSet = null;
JSONArray jsonarray_listedBrands = new JSONArray();
JSONObject jsonObj_allbrands = new JSONObject();
try
{
dbConnection = DBConnectionOrient.getDBConnection();
getAllBrandsPst = dbConnection.prepareStatement("select distinct listedBrandName,listedbrandID from tbl_listedBrand group by listedBrandName");
getAllBrandsResltSet = getAllBrandsPst.executeQuery();
while(getAllBrandsResltSet.next())
{
//
}
jsonObj_allbrands.put("brands", jsonarray_listedBrands);
}
catch(Exception e)
{
logger.error("Exception Occured" , e);
}
finally
{
DBConnectionOrient.close(getAllBrandsPst,getAllBrandsResltSet);
DBConnectionOrient.close(dbConnection);
}
String response = "jsonCallback("+jsonObj_allbrands.toString()+")";
return response;
}
}
这是我在日志中遇到的异常
SEVERE: Unable to create initial connections of pool.
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1014)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:988)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:974)
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1110)
at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2465)
at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2498)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2283)
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:822)
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47)
at sun.reflect.GeneratedConstructorAccessor10.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:404)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:317)
at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:278)
at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:182)
at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:701)
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:635)
at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:486)
at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:144)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:116)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:103)
at org.apache.tomcat.jdbc.pool.DataSourceFactory.createDataSource(DataSourceFactory.java:554)
at org.apache.tomcat.jdbc.pool.DataSourceFactory.getObjectInstance(DataSourceFactory.java:242)
at org.apache.naming.factory.ResourceFactory.getObjectInstance(ResourceFactory.java:141)
at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
at org.apache.naming.NamingContext.lookup(NamingContext.java:842)
at org.apache.naming.NamingContext.lookup(NamingContext.java:153)
at org.apache.naming.NamingContext.lookup(NamingContext.java:830)
at org.apache.naming.NamingContext.lookup(NamingContext.java:167)
at org.apache.catalina.core.NamingContextListener.addResource(NamingContextListener.java:1103)
at org.apache.catalina.core.NamingContextListener.createNamingContext(NamingContextListener.java:682)
at org.apache.catalina.core.NamingContextListener.lifecycleEvent(NamingContextListener.java:271)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:731)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.startup.Catalina.start(Catalina.java:689)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:321)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:455)
如果有多个我可以这样走吗
finally {
try {
DBConnectionOrient.close(getAllBrandsPst,getAllBrandsResltSet);
DBConnectionOrient.close(getAllBrandsPst2,getAllBrandsResltSet2);
} catch (Exception e) {}
try {
DBConnectionOrient.close(dbConnection);
} catch (Exception e) {}
}
我发现您的代码存在一个潜在问题,可能 是某些未关闭的悬挂数据库连接的来源。我提请您注意以下两行代码:
DBConnectionOrient.close(getAllBrandsPst,getAllBrandsResltSet);
DBConnectionOrient.close(dbConnection);
认识到如果在第一次调用DBConnectionOrient.close()
语句和结果集时发生异常,那么数据库连接将永远不会关闭。更安全的方法如下:
finally {
try {
DBConnectionOrient.close(getAllBrandsPst,getAllBrandsResltSet);
} catch (Exception e) {}
try {
DBConnectionOrient.close(dbConnection);
} catch (Exception e) {}
}
现在,即使关闭语句和结果集出现问题,仍然会尝试关闭数据库连接。
以下是您在 JDBC 通话中应遵循的一般模因:
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
try {
// get a connection, statement and result set, in this order
// make your JDBC calls here
} catch (Exception e) {
// handle all exceptions here
} finally {
try {
try {rs.close();} catch (Exception e) {}
try {stmt.close();} catch (Exception e) {}
// Note that we will attempt to close the database connection even
// if something went wrong with closing the statement or result set
try {con.close();} catch (Exception e) {}
} catch (Exception e) { }
}
我正在使用 mysql 5.0,我经常收到数据太多连接错误,我确信我正在关闭我的 finally 块中的所有连接
这是我的 class 用于获取数据库连接
public class DBConnection {
final static Logger logger = Logger.getLogger(DBConnection.class);
private static DataSource dataSource;
static {
try {
dataSource = (DataSource) new InitialContext().lookup("java:/comp/env/jdbc/REDEX");
} catch (NamingException e) {
logger.error("NamingException Occured" , e);
e.printStackTrace();
try {
// throw new Exception("'jndifordbconc' not found in JNDI",e);
} catch (Exception e1) {
//logger.error("Exception Occured" , e1);
logger.error("NamingException Occured" , e1);
e1.printStackTrace();
}
}
}
public static Connection getDBConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
logger.error("Exception Occured Under getDBConnection" , e);
return null;
}
}
public static void close(Connection con)
{
if (con != null)
{
try
{
con.close();
}
catch (SQLException e)
{
logger.error("Exception Occured inside close " , e);
}
}
}
public static void close(Statement stmt, ResultSet rs)
{
if (rs != null)
{
try
{
rs.close();
}
catch (SQLException e)
{
logger.error("Exception Occured while closing resultset " , e);
}
}
if (stmt != null)
{
try
{
stmt.close();
}
catch (SQLException e)
{
logger.error("Exception Occured while closing statement " , e);
}
}
}
}
连接池设置
<ResourceLink name="jdbc/REDEX"
global="jdbc/REDEX"
type="javax.sql.DataSource" />
<Resource name="jdbc/REDEX"
global="jdbc/REDEX"
type="javax.sql.DataSource"
auth="Container"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/REDEX?allowMultiQueries=true"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
username="root"
password="xxxxx@123"
initialSize="100"
maxActive="100"
maxIdle="20"
minIdle="10"
suspectTimeout="60"
timeBetweenEvictionRunsMillis="30000"
minEvictableIdleTimeMillis="60000"
validationQuery="SELECT 1"
validationInterval="34000"
testOnBorrow="true"
removeAbandoned="true"
removeAbandonedTimeout="55"
/>
示例 java class 我如何使用连接和关闭
public class GetBrands {
final static Logger logger = Logger.getLogger(GetBrands.class);
@GET
@Consumes("application/text")
@Produces("application/json")
public String getAllBrands() throws JSONException
{
logger.error("the GetBrands got called");
Connection dbConnection = null;
PreparedStatement getAllBrandsPst = null ;
ResultSet getAllBrandsResltSet = null;
JSONArray jsonarray_listedBrands = new JSONArray();
JSONObject jsonObj_allbrands = new JSONObject();
try
{
dbConnection = DBConnectionOrient.getDBConnection();
getAllBrandsPst = dbConnection.prepareStatement("select distinct listedBrandName,listedbrandID from tbl_listedBrand group by listedBrandName");
getAllBrandsResltSet = getAllBrandsPst.executeQuery();
while(getAllBrandsResltSet.next())
{
//
}
jsonObj_allbrands.put("brands", jsonarray_listedBrands);
}
catch(Exception e)
{
logger.error("Exception Occured" , e);
}
finally
{
DBConnectionOrient.close(getAllBrandsPst,getAllBrandsResltSet);
DBConnectionOrient.close(dbConnection);
}
String response = "jsonCallback("+jsonObj_allbrands.toString()+")";
return response;
}
}
这是我在日志中遇到的异常
SEVERE: Unable to create initial connections of pool.
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1014)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:988)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:974)
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1110)
at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2465)
at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2498)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2283)
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:822)
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47)
at sun.reflect.GeneratedConstructorAccessor10.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:404)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:317)
at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:278)
at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:182)
at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:701)
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:635)
at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:486)
at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:144)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:116)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:103)
at org.apache.tomcat.jdbc.pool.DataSourceFactory.createDataSource(DataSourceFactory.java:554)
at org.apache.tomcat.jdbc.pool.DataSourceFactory.getObjectInstance(DataSourceFactory.java:242)
at org.apache.naming.factory.ResourceFactory.getObjectInstance(ResourceFactory.java:141)
at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
at org.apache.naming.NamingContext.lookup(NamingContext.java:842)
at org.apache.naming.NamingContext.lookup(NamingContext.java:153)
at org.apache.naming.NamingContext.lookup(NamingContext.java:830)
at org.apache.naming.NamingContext.lookup(NamingContext.java:167)
at org.apache.catalina.core.NamingContextListener.addResource(NamingContextListener.java:1103)
at org.apache.catalina.core.NamingContextListener.createNamingContext(NamingContextListener.java:682)
at org.apache.catalina.core.NamingContextListener.lifecycleEvent(NamingContextListener.java:271)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:731)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.startup.Catalina.start(Catalina.java:689)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:321)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:455)
如果有多个我可以这样走吗
finally {
try {
DBConnectionOrient.close(getAllBrandsPst,getAllBrandsResltSet);
DBConnectionOrient.close(getAllBrandsPst2,getAllBrandsResltSet2);
} catch (Exception e) {}
try {
DBConnectionOrient.close(dbConnection);
} catch (Exception e) {}
}
我发现您的代码存在一个潜在问题,可能 是某些未关闭的悬挂数据库连接的来源。我提请您注意以下两行代码:
DBConnectionOrient.close(getAllBrandsPst,getAllBrandsResltSet);
DBConnectionOrient.close(dbConnection);
认识到如果在第一次调用DBConnectionOrient.close()
语句和结果集时发生异常,那么数据库连接将永远不会关闭。更安全的方法如下:
finally {
try {
DBConnectionOrient.close(getAllBrandsPst,getAllBrandsResltSet);
} catch (Exception e) {}
try {
DBConnectionOrient.close(dbConnection);
} catch (Exception e) {}
}
现在,即使关闭语句和结果集出现问题,仍然会尝试关闭数据库连接。
以下是您在 JDBC 通话中应遵循的一般模因:
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
try {
// get a connection, statement and result set, in this order
// make your JDBC calls here
} catch (Exception e) {
// handle all exceptions here
} finally {
try {
try {rs.close();} catch (Exception e) {}
try {stmt.close();} catch (Exception e) {}
// Note that we will attempt to close the database connection even
// if something went wrong with closing the statement or result set
try {con.close();} catch (Exception e) {}
} catch (Exception e) { }
}