⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbconnectiondefaultpool.java

📁 Jive Forums 1.0 src
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
         * dbPassword:      Database password.    e.g. 'Tiger'<br>
         * minConns:        Minimum number of connections to start with.<br>
         * 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) {
                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) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -