繁体中文
设为首页
加入收藏
当前位置:JSP技术首页 >> 资料/其它 >> 一个连接池的例子(来自JIVE)(2)

一个连接池的例子(来自JIVE)(2)

2005-01-15 08:00:00  作者:  来源:互联网  浏览次数:0  文字大小:【】【】【
简介://文件:DbConnectionDefaultPool.java的第二部分 /** * Housekeeping thread. Runs in the background with low CPU overhead. * Connections are checked for warnings and closure and are periodically * r...
关键字:例子 一个 JIVE

//文件:DbConnectionDefaultPool.java的第二部分

/**

* 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";

}

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 {

log.println("----> Could not free connection!!!");

}

return res;

}

责任编辑:admin
相关文章