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

📄 dbconnectionmanager.java

📁 一个用jsp技术实现的新闻发布系统
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		    }

		    try {
			createConn(i);
		    } catch(SQLException e1) {
			if(debugLevel > 0) {
			    log.println("Failed to create connection: " + 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) {
		    log.println("Error: " + e1);
		}
            
                if(gotOne) {
                    break;
                } else {
                    synchronized(this) {  // Add new connections to the pool
                        if(currConnections < maxConns) {
                            
                            try {
                                createConn(currConnections);
				currConnections++;
                            } catch(SQLException e) {
				if(debugLevel > 0) {
				    log.println("Error: Unable to create new connection: " + e);
				}
                            }
                        }
                    }
                    
                    try { Thread.sleep(2000); }
                    catch(InterruptedException e) {}
		    if(debugLevel > 0) {
			log.println("-----> Connections Exhausted!  Will wait and try again in loop " + 
				    String.valueOf(outerloop));
		    }
                }
                
            } // End of try 10 times loop
            
        } else {
	    if(debugLevel > 0) {
		log.println("Unsuccessful getConnection() request during destroy()");
	    }
        } // End if(available)    
                    
	if(debugLevel > 2) {
	    log.println("Handing out connection " + 
			idOfConnection(conn) + " --> " +
			(new SimpleDateFormat("MM/dd/yyyy  hh:mm:ss a")).format(new java.util.Date()));
	}

        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";
        }
        
        match=-1;
        
        for(int i=0; i< currConnections; i++) {
            if(connID[i].equals(tag)) {
                match = i;
                break;
            }
        }
        return match;
    }
    
    /**
     * Frees a connection.  Replaces connection back into the main pool for
     * reuse.
     */
    public String freeConnection(Connection conn) {
        String res="";
        
        int thisconn = idOfConnection(conn);
        if(thisconn >= 0) {
            connStatus[thisconn]=0;
            res = "freed " + conn.toString();
            //log.println("Freed connection " + String.valueOf(thisconn) +
            //            " normal exit: ");
        } else {
	    if(debugLevel > 0) {
		log.println("----> Error: Could not free connection!!!");
	    }
        }
        
        return res;
         
    }
    
    /**
     * Returns the age of a connection -- the time since it was handed out to
     * an application.
     */
    public long getAge(Connection conn) { // Returns the age of the connection in millisec.
        int thisconn = idOfConnection(conn);
        return System.currentTimeMillis() - connLockTime[thisconn];
    }

    private void createConn(int i) 

        throws SQLException {

        Date now = new Date();
        
        try {
            Class.forName (dbDriver);
        
            connPool[i] = DriverManager.getConnection 
                          (dbServer,dbLogin,dbPassword);
                           
            connStatus[i]=0;
            connID[i]=connPool[i].toString();
            connLockTime[i]=0;
            connCreateDate[i] =  now.getTime();
        } catch (ClassNotFoundException e2) {
	    if(debugLevel > 0) {
		log.println("Error creating connection: " + e2);
	    }
	}
                
        log.println(now.toString() + "  Opening connection " + String.valueOf(i) + 
                    " " + connPool[i].toString() + ":");
    }
    
    /**
     * Shuts down the housekeeping thread and closes all connections 
     * in the pool. Call this method from the destroy() method of the servlet.
     */

    /**
     * Multi-phase shutdown.  having following sequence:
     * <OL>
     * <LI><code>getConnection()</code> will refuse to return connections.
     * <LI>The housekeeping thread is shut down.<br>
     *    Up to the time of <code>millis</code> milliseconds after shutdown of
     *    the housekeeping thread, <code>freeConnection()</code> can still be
     *    called to return used connections.
     * <LI>After <code>millis</code> milliseconds after the shutdown of the
     *    housekeeping thread, all connections in the pool are closed.
     * <LI>If any connections were in use while being closed then a
     *    <code>SQLException</code> is thrown.
     * <LI>The log is closed.
     * </OL><br>
     * Call this method from a servlet destroy() method.
     *
     * @param      millis   the time to wait in milliseconds.
     * @exception  SQLException if connections were in use after 
     * <code>millis</code>.
     */
    public void destroy(int millis) throws SQLException {
    
        // Checking for invalid negative arguments is not necessary,
        // Thread.join() does this already in runner.join().

        // Stop issuing connections
        available=false;

        // Shut down the background housekeeping thread
        runner.interrupt();

        // Wait until the housekeeping thread has died.
        try { runner.join(millis); } 
        catch(InterruptedException e){} // ignore 
        
        // The housekeeping thread could still be running
        // (e.g. if millis is too small). This case is ignored.
        // At worst, this method will throw an exception with the 
	// clear indication that the timeout was too short.

        long startTime=System.currentTimeMillis();

        // Wait for freeConnection() to return any connections
        // that are still used at this time.
        int useCount;
        while((useCount=getUseCount())>0 && System.currentTimeMillis() - startTime <=  millis) {
            try { Thread.sleep(500); }
            catch(InterruptedException e) {} // ignore 
        }

        // Close all connections, whether safe or not
        for(int i=0; i < currConnections; i++) {
            try {
                connPool[i].close();
            } catch (SQLException e1) {
		if(debugLevel > 0) {
		    log.println("Cannot close connections on Destroy");
		}
            }
        }

        if(useCount > 0) {
            //bt-test successful
            String msg="Unsafe shutdown: Had to close "+useCount+
		" active DB connections after "+millis+"ms";
            log.println(msg);
            // Close all open files
            log.close();
            // Throwing following Exception is essential because servlet authors
            // are likely to have their own error logging requirements.
            throw new SQLException(msg);
        }

        // Close all open files
        log.close();

    }//End destroy()


    /**
     * Less safe shutdown.  Uses default timeout value.
     * This method simply calls the <code>destroy()</code> method 
     * with a <code>millis</code>
     * value of 10000 (10 seconds) and ignores <code>SQLException</code> 
     * thrown by that method.
     * @see     #destroy(int)
     */
    public void destroy() { 
        try {
            destroy(10000);
        }
        catch(SQLException e) {}
    }



    /**
     * Returns the number of connections in use.
     */
    // This method could be reduced to return a counter that is
    // maintained by all methods that update connStatus.
    // However, it is more efficient to do it this way because:
    // Updating the counter would put an additional burden on the most
    // frequently used methods; in comparison, this method is
    // rarely used (although essential).
    public int getUseCount() {
        int useCount=0;
        synchronized(connStatus) {
            for(int i=0; i < currConnections; i++) {
                if(connStatus[i] > 0) { // In use
                    useCount++;
                }
            }
        }
        return useCount;
    }//End getUseCount()

    /**
     * Returns the number of connections in the dynamic pool.
     */
    public int getSize() {
        return currConnections;
    }//End getSize()

}// End class
               

⌨️ 快捷键说明

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