提问者:小点点

代码会对MySQL可用连接产生任何影响吗?


我开发了一个Java的Web应用程序,它使用JDBC连接器连接到MySQL数据库,并创建2个连接池。该应用程序部署在tomcat服务器上。

我的问题是,如果我多次部署应用程序,并且当我关闭tomcat时,代码没有任何行来关闭可用连接,那么这段代码会影响MySQL可用连接吗?重新启动时tomcat会负责关闭连接吗?

连接Util:

import javax.sql.DataSource;

import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.impl.GenericObjectPool;

public class MySQLConnectionPool {


     public static DataSource setUpPool(){

         GenericObjectPool gPool = null;
         String dbName = "DBName";
         String userName = "Username";
         String password = "Password";
         String hostname = "Host";
         String port = "Port";
         try {
             Class.forName("com.mysql.jdbc.Driver");
            // Creates an Instance of GenericObjectPool That Holds Our Pool of Connections Object!
                gPool = new GenericObjectPool();
                gPool.setMaxActive(2);

                // Creates a ConnectionFactory Object Which Will Be Use by the Pool to Create the Connection Object!
                ConnectionFactory cf = new DriverManagerConnectionFactory("jdbc:mysql://" + hostname + ":" + port + "/" + dbName, userName, password);

                // Creates a PoolableConnectionFactory That Will Wraps the Connection Object Created by the ConnectionFactory to Add Object Pooling Functionality!
                PoolableConnectionFactory pcf = new PoolableConnectionFactory(cf, gPool, null, null, false, true);
         }catch (Exception e) {
            // TODO: handle exception
             System.out.println("Error: "+e.toString());
        }

            return new PoolingDataSource(gPool);
     }

}

DAO:

@Override
public ArrayList<User> getUserDetails(String environment, String MySQLQuery) {
    // TODO Auto-generated method stub
    ArrayList<User> users = new ArrayList<User>();
    Connection connObj = null;
    Statement stmt = null;
    ResultSet result = null;
    try {   
        DataSource dataSource = MySQLConnectionPool.setUpPool();

        // Performing Database Operation!
        System.out.println("\n=====Making A New Connection Object For Db Transaction=====\n");
        connObj = dataSource.getConnection();

        stmt = connObj.createStatement();
        result = stmt.executeQuery(MySQLQuery);
        while(result.next()) {
            //Some code here
        }

        System.out.println("\n=====Releasing Connection Object To Pool=====\n");            
    } catch(Exception sqlException) {

    } finally {
        try {
            // Closing ResultSet Object
            if(result != null) {
                result.close();
            }
            // Closing Statement Object
            if(stmt != null) {
                stmt.close();
            }
            // Closing Connection Object
            if(connObj != null) {
                connObj.close();
            }
        } catch(Exception sqlException) {

        }
    }
    return users;
}

共1个答案

匿名用户

如果停止整个tomcat,则与数据库的连接将关闭,因为运行Tomcat的java可执行文件将在停止时释放连接。

即使你不停止服务器,如果Java决定你的Connection对象不再使用,那么它将被垃圾回收。你只是不知道什么时候。

另一方面:

  • 您可能应该寻找将DataSource嵌入服务器并从服务器获取DataSource的方法:此页面可能会有所帮助。
  • 您应该重写您的代码,以便在资源(Java7)中使用try,这些资源会正确关闭您的资源(您的代码错误)。

使用资源尝试:

DataSource dataSource = MySQLConnectionPool.setUpPool();
try (Connection connObj = dataSource.getConnection()) {   
  try (Statement stmt = connObj.createStatement()) {
    try (ResultSet result = stmt.executeQuery(MySQLQuery)) {
      while(result.next()) {
        //Some code here
      }
    }
  } 
} catch (SQLException sqlException) {
  // do something
}

或者:

DataSource dataSource = MySQLConnectionPool.setUpPool();
try (Connection connObj = dataSource.getConnection();
     Statement stmt = connObj.createStatement();
     ResultSet result = stmt.executeQuery(MySQLQuery)
    ) {
  while(result.next()) {
    //Some code here
  }
} catch (SQLException sqlException) {
  // do something
}

正如我上面所说,您的代码是错误的,因为您在关闭ResultSet语句时可能会出现异常(至少是SQLException),因此您的代码永远不会释放后面的对象:

    try {
        // Closing ResultSet Object
        if(result != null) {
            result.close(); // if it fails, stmt and connObj are not closed.
        }
        // Closing Statement Object
        if(stmt != null) {
            stmt.close(); // if it fails, connObj is not closed.
        }
        // Closing Connection Object
        if(connObj != null) {
            connObj.close();
        }
    } catch(Exception sqlException) {

    }

如果你不能在资源中使用try(Java6可能已经几十年不支持了,但谁知道呢),那么你的代码应该是这样的:

Connection connObj = null;
Statement stmt = null;
ResultSet result = null;
try {
  // ... do whatever is needed
} finally {
  if(result != null) {
    try {result.close();} catch (Exception ignored) {}
  }
  if(stmt != null) {
    try {stmt.close();} catch (Exception ignored) {}
  }
  if(connObj != null) {
    try {connObj .close();} catch (Exception ignored) {}
  }
}