该代码对MySQL可用连接有影响吗?

时间:2019-01-30 19:11:20

标签: java tomcat jdbc datasource

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

我的问题是,如果我多次部署应用程序,并且当我关闭tomcat时,该代码没有任何行可以关闭可用连接,此代码是否会影响MySQL可用连接? Tomcat重新启动时是否会关闭连接?

连接实用程序:

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 个答案:

答案 0 :(得分:0)

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

即使您不停止服务器,如果Java决定不再使用Connection对象,也将对其进行垃圾回收。你只是不知道什么时候。

关于其他说明:

  • 您可能应该寻找将DataSource嵌入服务器并从服务器获取DataSource的方法:此page可能会有所帮助。
  • 您应该重写代码以对资源使用 try (Java 7 ++),这样可以正确关闭资源(您的代码错误)。

使用尝试使用资源

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
}

如上所述,您的代码是错误的,因为关闭SQLExceptionResultSet时,您可能会有一个异常(至少是一个Statement),因此后面的对象永远不会被您的代码释放:

    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 (可能几十年来不再支持Java 6,但是谁知道呢),那么您的代码应该像这样:

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) {}
  }
}