package ConnectionPool; import java.sql.*; import java.io.*; import java.util.*; /** * Manages a java.sql.Connection pool. * * @author Anil Hemrajani */ public class DBConnectionMgr { /// Fields // ¿¬°á ±âº» Á¤º¸ private PrintWriter log; // ¿¡·¯ ÀúÀå¿ë ·Î±×ÆÄÀÏ private String _driver; private String _url; private String _user; private String _password; private Vector connections; // ¹Ì¸® ¿­¾î³õÀº Connection °´Ã¼µéÀ» º¸°üÇÑ´Ù. // Ãʱ⠿¬°á ¼ýÀÚ private int initialCons = 0; // ÃÖ´ë ¿¬°á ¼ýÀÚ private int maxCons = 0; /* _url = "jdbc:oracle:thin:@192.168.1.10:1521:itea", _user = "scott", _password = "tiger";*/ private boolean _traceOn = false; private boolean initialized = false; private int _openConnections ; private static DBConnectionMgr instance = null; /// Constructor private DBConnectionMgr() { try { log = new PrintWriter(new FileWriter("PoolLog.txt", true), true); } catch (IOException e) { System.err.println("Can't open the log file: PoolLog.txt"); log = new PrintWriter(System.err); } try{ setPoolProperty(); } catch (Exception e){ log(e,"Init Pool Error"); } connections = new Vector(initialCons); _openConnections = initialCons; } /// Method /** Use this method to set the maximum number of open connections before unused connections are closed. */ private void setPoolProperty() throws IOException{ BufferedReader br = new BufferedReader(new FileReader("Pool.properties")); String str = ""; while((str = br.readLine()) != null){ StringTokenizer st = new StringTokenizer(str,"="); String next = st.nextToken(); if(next.equals("JDBCDriverClass")){ _driver = st.nextToken(); } else if(next.equals("url")){ _url = st.nextToken(); } else if(next.equals("user")){ _user = st.nextToken(); } else if(next.equals("password")){ _password = st.nextToken(); } else if(next.equals("initialCons")){ initialCons = Integer.parseInt(st.nextToken()); } else if(next.equals("maxCons")){ maxCons = Integer.parseInt(st.nextToken()); } } } public void log(String msg) { log.println(new java.util.Date() + ": " + msg); } private void log(Throwable e, String msg) { log.println(new java.util.Date() + ": " + msg); e.printStackTrace(log); } public static DBConnectionMgr getInstance() { if (instance == null) { synchronized (DBConnectionMgr.class) { if (instance == null) { instance = new DBConnectionMgr(); } } } return instance; } public void setOpenConnectionCount(int count) { _openConnections = count; } public void setEnableTrace(boolean enable) { _traceOn = enable; } /** Returns a Vector of java.sql.Connection objects */ public Vector getConnectionList() { return connections; } /** Opens specified "count" of connections and adds them to the existing pool */ public synchronized void setInitOpenConnections(int count) throws SQLException { Connection c = null; ConnectionObject co = null; for (int i = 0; i < count; i++) { c = createConnection(); co = new ConnectionObject(c, false); connections.addElement(co); trace("ConnectionPoolManager: Adding new DB connection to pool (" + connections.size() + ")"); } } /** Returns a count of open connections */ public int getConnectionCount() { return connections.size(); } /** Returns an unused existing or new connection. */ public synchronized Connection getConnection() throws Exception { if (!initialized) { Class c = Class.forName(_driver); DriverManager.registerDriver((Driver) c.newInstance()); initialized = true; } Connection c = null; ConnectionObject co = null; boolean badConnection = false; for (int i = 0; i < connections.size(); i++) { co = (ConnectionObject) connections.elementAt(i); // If connection is not in use, test to ensure it's still valid! if (!co.inUse) { try { badConnection = co.connection.isClosed(); if (!badConnection) badConnection = (co.connection.getWarnings() != null); } catch (Exception e) { badConnection = true; e.printStackTrace(); } // Connection is bad, remove from pool if (badConnection) { connections.removeElementAt(i); trace("ConnectionPoolManager: Remove disconnected DB connection #" + i); continue; } c = co.connection; co.inUse = true; trace("ConnectionPoolManager: Using existing DB connection #" + (i + 1)); break; } } if (c == null) { c = createConnection(); co = new ConnectionObject(c, true); connections.addElement(co); trace("ConnectionPoolManager: Creating new DB connection #" + connections.size()); } return c; } /** Marks a flag in the ConnectionObject to indicate this connection is no longer in use */ public synchronized void freeConnection(Connection c) { if (c == null) return; ConnectionObject co = null; for (int i = 0; i < connections.size(); i++) { co = (ConnectionObject) connections.elementAt(i); if (c == co.connection) { co.inUse = false; break; } } for (int i = 0; i < connections.size(); i++) { co = (ConnectionObject) connections.elementAt(i); if ((i + 1) > _openConnections && !co.inUse) removeConnection(co.connection); } } public void freeConnection(Connection c, PreparedStatement p, ResultSet r) { try { if (r != null) r.close(); if (p != null) p.close(); freeConnection(c); } catch (SQLException e) { e.printStackTrace(); } } public void freeConnection(Connection c, Statement s, ResultSet r) { try { if (r != null) r.close(); if (s != null) s.close(); freeConnection(c); } catch (SQLException e) { e.printStackTrace(); } } public void freeConnection(Connection c, PreparedStatement p) { try { if (p != null) p.close(); freeConnection(c); } catch (SQLException e) { e.printStackTrace(); } } public void freeConnection(Connection c, Statement s) { try { if (s != null) s.close(); freeConnection(c); } catch (SQLException e) { e.printStackTrace(); } } /** Marks a flag in the ConnectionObject to indicate this connection is no longer in use */ public synchronized void removeConnection(Connection c) { if (c == null) return; ConnectionObject co = null; for (int i = 0; i < connections.size(); i++) { co = (ConnectionObject) connections.elementAt(i); if (c == co.connection) { try { c.close(); connections.removeElementAt(i); trace("Removed " + c.toString()); } catch (Exception e) { e.printStackTrace(); } break; } } } private Connection createConnection() throws SQLException { Connection con = null; try { if (_user == null) _user = ""; if (_password == null) _password = ""; Properties props = new Properties(); props.put("user", _user); props.put("password", _password); con = DriverManager.getConnection(_url, props); } catch (Throwable t) { throw new SQLException(t.getMessage()); } return con; } /** Closes all connections and clears out the connection pool */ public void releaseFreeConnections() { trace("ConnectionPoolManager.releaseFreeConnections()"); Connection c = null; ConnectionObject co = null; for (int i = 0; i < connections.size(); i++) { co = (ConnectionObject) connections.elementAt(i); if (!co.inUse) removeConnection(co.connection); } } /** Closes all connections and clears out the connection pool */ public void finalize() { trace("ConnectionPoolManager.finalize()"); Connection c = null; ConnectionObject co = null; for (int i = 0; i < connections.size(); i++) { co = (ConnectionObject) connections.elementAt(i); try { co.connection.close(); } catch (Exception e) { e.printStackTrace(); } co = null; } connections.removeAllElements(); } private void trace(String s) { if (_traceOn) System.err.println(s); } } class ConnectionObject { public java.sql.Connection connection = null; public boolean inUse = false; public ConnectionObject(Connection c, boolean useFlag) { connection = c; inUse = useFlag; } }