📄 dbconnectiondefaultpool.java
字号:
* maxConns: Maximum number of connections in dynamic pool.<br> * logFileString: Absolute path name for log file. e.g. 'c:\temp\mylog.log' <br> * maxConnTime: Time in days between connection resets. (Reset does a basic cleanup)<br> */ public ConnectionPool (String dbDriver, String dbServer, String dbLogin, String dbPassword, int minConns, int maxConns, String logFileString, double maxConnTime) throws IOException { connPool = new Connection[maxConns]; connStatus = new int[maxConns]; connLockTime = new long[maxConns]; connCreateDate = new long[maxConns]; connID = new String[maxConns]; currConnections = minConns; this.maxConns = maxConns; this.dbDriver = dbDriver; this.dbServer = dbServer; this.dbLogin = dbLogin; this.dbPassword = dbPassword; this.logFileString = logFileString; maxConnMSec = (int)(maxConnTime * 86400000.0); //86400 sec/day if(maxConnMSec < 30000) { // Recycle no less than 30 seconds. maxConnMSec = 30000; } try { log = new PrintWriter(new FileOutputStream(logFileString),true); // Can't open the requested file. Open the default file. } catch (IOException e1) { System.err.println("Warning: DbConnectionDefaultPool could not open \"" + logFileString + "\" to write log to. Make sure that your Java " + "process has permission to write to the file and that the directory exists." ); try { log = new PrintWriter(new FileOutputStream("DCB_" + System.currentTimeMillis() + ".log"), true ); } catch (IOException e2) { throw new IOException("Can't open any log file"); } } // Write the pid file (used to clean up dead/broken connection) SimpleDateFormat formatter = new SimpleDateFormat ("yyyy.MM.dd G 'at' hh:mm:ss a zzz"); java.util.Date nowc = new java.util.Date(); pid = formatter.format(nowc); BufferedWriter pidout = new BufferedWriter(new FileWriter(logFileString + "pid")); pidout.write(pid); pidout.close(); log.println("Starting ConnectionPool:"); log.println("dbDriver = " + dbDriver); log.println("dbServer = " + dbServer); log.println("dbLogin = " + dbLogin); log.println("log file = " + logFileString); log.println("minconnections = " + minConns); log.println("maxconnections = " + maxConns); log.println("Total refresh interval = " + maxConnTime + " days"); log.println("-----------------------------------------"); // Initialize the pool of connections with the mininum connections: // Problems creating connections may be caused during reboot when the // servlet is started before the database is ready. Handle this // by waiting and trying again. The loop allows 5 minutes for // db reboot. boolean connectionsSucceeded=false; int dbLoop=20; try { for(int i=1; i < dbLoop; i++) { try { for(int j=0; j < currConnections; j++) { createConn(j); } connectionsSucceeded=true; break; } catch (SQLException e){ log.println("--->Attempt (" + String.valueOf(i) + " of " + String.valueOf(dbLoop) + ") failed to create new connections set at startup: "); log.println(" " + e); log.println(" Will try again in 15 seconds..."); try { Thread.sleep(15000); } catch(InterruptedException e1) {} } } if(!connectionsSucceeded) { // All attempts at connecting to db exhausted log.println("\r\nAll attempts at connecting to Database exhausted"); throw new IOException(); } } catch (Exception e) { e.printStackTrace(); throw new IOException(); } // Fire up the background housekeeping thread runner = new Thread(this); runner.start(); } //End ConnectionPool() /** * Housekeeping thread. Runs in the background with low CPU overhead. * Connections are checked for warnings and closure and are periodically * restarted. * This thread is a catchall for corrupted * connections and prevents the buildup of open cursors. (Open cursors * result when the application fails to close a Statement). * This method acts as fault tolerance for bad connection/statement programming. */ public void run() { boolean forever = true; Statement stmt=null; String currCatalog=null; while(forever) { // Make sure the log file is the one this instance opened // If not, clean it up! try { BufferedReader in = new BufferedReader(new FileReader(logFileString + "pid")); String curr_pid = in.readLine(); if(curr_pid.equals(pid)) { //log.println("They match = " + curr_pid); } else { //log.println("No match = " + curr_pid); log.close(); // Close all connections silently - they are definitely dead. for(int i=0; i < currConnections; i++) { try { connPool[i].close(); } catch (SQLException e1) {} // ignore } // Returning from the run() method kills the thread return; } in.close(); } catch (IOException e1) { log.println("Can't read the file for pid info: " + logFileString + "pid"); } // Get any Warnings on connections and print to event file for(int i=0; i < currConnections; i++) { try { currSQLWarning = connPool[i].getWarnings(); if(currSQLWarning != null) { log.println("Warnings on connection " + String.valueOf(i) + " " + currSQLWarning); connPool[i].clearWarnings(); } } catch(SQLException e) { log.println("Cannot access Warnings: " + e); } } for(int i=0; i < currConnections; i++) { // Do for each connection long age = System.currentTimeMillis() - connCreateDate[i]; synchronized(connStatus) { if(connStatus[i] > 0) { // In use, catch it next time! continue; } connStatus[i] = 2; // Take offline (2 indicates housekeeping lock) } try { // Test the connection with createStatement call if(age > maxConnMSec) { // Force a reset at the max conn time throw new SQLException(); } stmt = connPool[i].createStatement(); connStatus[i] = 0; // Connection is O.K. //log.println("Connection confirmed for conn = " + // String.valueOf(i)); // Some DBs return an object even if DB is shut down if(connPool[i].isClosed()) { throw new SQLException(); } // Connection has a problem, restart it } catch(SQLException e) { try { log.println(new Date().toString() + " ***** Recycling connection " + String.valueOf(i) + ":" ); connPool[i].close(); createConn(i); } catch(SQLException e1) { log.println("Failed: " + e1); connStatus[i] = 0; // Can't open, try again next time } } finally { try { if(stmt != null) { stmt.close(); } } catch(SQLException e1){}; } } try { Thread.sleep(20000); } // Wait 20 seconds for next cycle catch(InterruptedException e) { // Returning from the run method sets the internal // flag referenced by Thread.isAlive() to false. // This is required because we don't use stop() to // shutdown this thread. return; } } } // End run /** * This method hands out the connections in round-robin order. * This prevents a faulty connection from locking * up an application entirely. A browser 'refresh' will * get the next connection while the faulty * connection is cleaned up by the housekeeping thread. * * If the min number of threads are ever exhausted, new * threads are added up the the max thread count. * Finally, if all threads are in use, this method waits * 2 seconds and tries again, up to ten times. After that, it * returns a null. */ public Connection getConnection() { Connection conn=null; if(available){ boolean gotOne = false; for(int outerloop=1; outerloop<=10; outerloop++) { try { int loop=0; int roundRobin = connLast + 1; if(roundRobin >= currConnections) roundRobin=0; do { synchronized(connStatus) { if((connStatus[roundRobin] < 1) && (! connPool[roundRobin].isClosed())) { conn = connPool[roundRobin]; connStatus[roundRobin]=1; connLockTime[roundRobin] = System.currentTimeMillis(); connLast = roundRobin; gotOne = true; break; } else { loop++; roundRobin++; if(roundRobin >= currConnections) roundRobin=0; } } } while((gotOne==false)&&(loop < currConnections)); } catch (SQLException e1) {} if(gotOne) { break; } else { synchronized(this) { // Add new connections to the pool if(currConnections < maxConns) { try { createConn(currConnections); currConnections++; } catch(SQLException e) { log.println("Unable to create new connection: " + e); } } } try { Thread.sleep(2000); } catch(InterruptedException e) {} log.println("-----> Connections Exhausted! Will wait and try " + "again in loop " + String.valueOf(outerloop)); } } // End of try 10 times loop } else { log.println("Unsuccessful getConnection() request during destroy()"); } // End if(available) return conn; } /** * Returns the local JDBC ID for a connection. */ public int idOfConnection(Connection conn) { int match; String tag; try { tag = conn.toString(); } catch (NullPointerException e1) { tag = "none";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -