Project

General

Profile

1 1087 tao
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A class represent a DBConnection pool. Another user can use the
4
 *    object to initial a connection pool, get db connection or return it.
5
 *  Copyright: 2000 Regents of the University of California and the
6
 *             National Center for Ecological Analysis and Synthesis
7
 *    Authors: Jing Tao
8
 *
9
 *   '$Author$'
10
 *     '$Date$'
11
 * '$Revision$'
12
 *
13
 * This program is free software; you can redistribute it and/or modify
14
 * it under the terms of the GNU General Public License as published by
15
 * the Free Software Foundation; either version 2 of the License, or
16
 * (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
 */
27
28
package edu.ucsb.nceas.metacat;
29
30
import java.io.*;
31
import java.util.Vector;
32 1089 tao
import java.lang.*;
33 1087 tao
import java.sql.*;
34
import java.util.Stack;
35
import java.util.Hashtable;
36
import java.util.Enumeration;
37
38 2663 sgarg
import org.apache.log4j.Logger;
39
40 1087 tao
/**
41
 * A class represent a DBConnection pool. Another user can use the
42
 * object to initial a connection pool, get db connection or return it.
43
 * This a singleton class, this means only one instance of this class could
44
 * be in the program at one time.
45
 */
46 1092 tao
public class DBConnectionPool implements Runnable
47 1087 tao
{
48 1089 tao
49 1087 tao
  //static attributes
50
  private static DBConnectionPool instance;
51
  private static Vector connectionPool;
52 1092 tao
  private static Thread runner;
53 1849 tao
  private static int countOfReachMaximum = 0;
54 2663 sgarg
  private static Logger logMetacat = Logger.getLogger(DBConnectionPool.class);
55
56 1089 tao
  //maximum connection number in the connection pool
57
  final static int MAXIMUMCONNECTIONNUMBER=
58 1087 tao
                  Integer.parseInt(MetaCatUtil.getOption("maximumConnections"));
59 1092 tao
60 1089 tao
  //inintila connection number int the connection pool
61
  final static int INITIALCONNECTIONNUMBER=
62 1087 tao
                  Integer.parseInt(MetaCatUtil.getOption("initialConnections"));
63 1092 tao
64 1089 tao
  //the number to increase connection pool size
65
  final static int INCREASECONNECTIONNUMBER=
66
                Integer.parseInt(MetaCatUtil.getOption("incrementConnections"));
67 1092 tao
68 1089 tao
  //maximum age for a connection (in milli seconds)
69
  final static long MAXIMUMAGE =
70
                  Long.parseLong(MetaCatUtil.getOption("maximumConnectionAge"));
71
  //maximum connection time for a connection ( in milli second)
72
  final static long MAXIMUMCONNECTIONTIME =
73
                 Long.parseLong(MetaCatUtil.getOption("maximumConnectionTime"));
74
  //maximum number for using a connection.
75
  final static int MAXIMUMUSAGENUMBER =
76 1095 tao
                  Integer.parseInt(MetaCatUtil.getOption("maximumUsageNumber"));
77
  //the parameter if run dbconncestionrecyclethread or not
78
  final static String DBCONNECTIONRECYCLETHREAD =
79
                          MetaCatUtil.getOption("runDBConnectionRecycleThread");
80
  //the cycle time of connection recycle action
81
  final static long CYCLETIMEOFDBCONNECTION =
82
               Long.parseLong(MetaCatUtil.getOption("cycleTimeOfDBConnection"));
83 1089 tao
84 1217 tao
  //the number for trying to check out a connection in the pool in
85
  //getDBConnection method
86
  final static int LIMIT = 2;
87 1089 tao
88
  final static int FREE = 0; //status of a connection
89
  final static int BUSY = 1; //statis of a connection
90 1087 tao
  /**
91
   * Returns the single instance, creating one if it's the
92
   * first time this method is called.
93
   */
94 1092 tao
  public static synchronized DBConnectionPool getInstance()
95 1089 tao
                                 throws SQLException
96 1087 tao
  {
97 2250 jones
    if (instance == null) {
98 1087 tao
      instance = new DBConnectionPool();
99 3078 jones
      Logger log = Logger.getLogger(DBConnectionPool.class);
100
      log.info("MaximumConnectionNumber: "+MAXIMUMCONNECTIONNUMBER);
101
      log.info("Intial connection number: "+INITIALCONNECTIONNUMBER);
102
      log.info("Increated connection Number: "+INCREASECONNECTIONNUMBER);
103
      log.info("Maximum connection age: "+MAXIMUMAGE);
104
      log.info("Maximum connection time: "+MAXIMUMCONNECTIONTIME);
105
      log.info("Maximum usage count: "+MAXIMUMUSAGENUMBER);
106
      log.info("Running recycle thread or not: "+DBCONNECTIONRECYCLETHREAD);
107
      log.info("Cycle time of recycle: "+CYCLETIMEOFDBCONNECTION);
108 1087 tao
    }
109
    return instance;
110 3078 jones
  }
111 1089 tao
112 1092 tao
113 1089 tao
  /**
114 1087 tao
   * This is a private constructor since it is singleton
115
   */
116
117 1089 tao
  private DBConnectionPool()  throws SQLException
118 1087 tao
  {
119 1092 tao
    connectionPool = new Vector();
120 1089 tao
    initialDBConnectionPool();
121 1092 tao
    //running the thread to recycle DBConnection
122 1095 tao
    if (DBCONNECTIONRECYCLETHREAD.equals("on"))
123
    {
124
      runner = new Thread(this);
125
      runner.start();
126
    }
127 1087 tao
  }//DBConnection
128 1092 tao
129
  /**
130
   * Method to get the size of DBConnectionPool
131
   */
132
  public int getSizeOfDBConnectionPool()
133
  {
134
    return connectionPool.size();
135
  }
136 1087 tao
137 1092 tao
138 1087 tao
  /**
139
   * Method to initial a pool of DBConnection objects
140
   */
141 1092 tao
  private void initialDBConnectionPool() throws SQLException
142
  {
143 1087 tao
144
    DBConnection dbConn = null;
145
146 1089 tao
    for ( int i = 0; i < INITIALCONNECTIONNUMBER; i++ )
147 1087 tao
    {
148
      //create a new object of DBConnection
149 1089 tao
      //this DBConnection object has a new connection in it
150
      //it automatically generate the createtime and tag
151 1087 tao
      dbConn = new DBConnection();
152
      //put DBConnection into vetor
153
      connectionPool.add(dbConn);
154
    }
155
156
157 1092 tao
  }//initialDBConnectionPool
158
159
  /**
160
   * Method to get Connection object (Not DBConnection)
161
   */
162
  /*public static Connection getConnection() throws SQLException
163
  {
164
    DBConnection dbConn = null;
165
    //get a DBConnection
166
    dbConn = getDBConnection();
167
    //get connection object in DBConnection object
168
    //The following getConnections method is in DBConnection class
169
    return dbConn.getConnections();
170
  }*/
171
172 1089 tao
173 1095 tao
  /**
174
   * Method to get a DBConnection in connection pool
175
   * 1) try to get a DBConnection from DBConnection pool
176
   * 2) if 1) failed, then check the size of pool. If the size reach the
177
   *    maximum number of connection, throw a exception: couldn't get one
178
   * 3) If the size is less than the maximum number of connectio, create some
179
   *    new connections and recursive get one
180
   * @param methodName, the name of method which will check connection out
181
   */
182
  public static synchronized DBConnection getDBConnection(String methodName)
183
                                                throws SQLException
184
  {
185 2250 jones
    if (instance == null) {
186
      instance = DBConnectionPool.getInstance();
187
    }
188 1095 tao
    DBConnection db = null;
189 1217 tao
    int random = 0; //random number
190
    int index = 0; //index
191
    int size = 0; //size of connection pool
192 2663 sgarg
    logMetacat.debug("Try to checking out connection...");
193 1217 tao
    size = connectionPool.size();
194 2663 sgarg
    logMetacat.debug("size of connection pool: "+size);
195 1217 tao
196
     //try every DBConnection in the pool
197
    //every DBConnection will be try LIMITE times
198
    for (int j=0 ; j<LIMIT; j++)
199
    {
200
       //create a random number as the started index for connection pool
201
      //So that the connection ofindex of 0 wouldn't be a the heaviest user
202
      random = (new Double (Math.random()*100)).intValue();
203
      for (int i=0; i<size; i++)
204 1095 tao
      {
205 1217 tao
        index =(i+random)%size;
206
        db = (DBConnection) connectionPool.elementAt(index);
207 2663 sgarg
        logMetacat.debug("Index: "+index);
208
        logMetacat.debug("Tag: "+db.getTag());
209
        logMetacat.debug("Status: "+db.getStatus());
210 1095 tao
        //check if the connection is free
211
        if (db.getStatus()==FREE)
212
        {
213
          //If this connection is good, return this DBConnection
214
          if (validateDBConnection(db))
215
          {
216
217
            //set this DBConnection status
218
            db.setStatus(BUSY);
219 1122 tao
            //increase checkout serial number
220
            db.increaseCheckOutSerialNumber(1);
221 1095 tao
            //increase one usageCount
222
            db.increaseUsageCount(1);
223
            //set method name to DBConnection
224
            db.setCheckOutMethodName(methodName);
225 1299 tao
            db.setAutoCommit(true);
226 1095 tao
            //debug message
227 2663 sgarg
            logMetacat.debug("The connection is checked out: "
228
                                       +db.getTag());
229
            logMetacat.debug("The method for checking is: "
230
                                              +db.getCheckOutMethodName());
231
            logMetacat.debug("The age is "+db.getAge());
232
            logMetacat.debug("The usage is "+db.getUsageCount());
233
            logMetacat.debug("The conection time it has: "
234
                                                +db.getConnectionTime());
235 1095 tao
            //set check out time
236
            db.setCheckOutTime(System.currentTimeMillis());
237 1849 tao
            // set count of reach maximum 0 because it can check out
238
            countOfReachMaximum =0;
239 1095 tao
            return db;
240
          }//if
241
          else//The DBConnection has some problem
242
          {
243
            //close this DBConnection
244
            db.close();
245
            //remove it form connection pool
246 1217 tao
            connectionPool.remove(index);
247 1095 tao
            //insert a new DBConnection to same palace
248
            db = new DBConnection();
249 1217 tao
            connectionPool.insertElementAt(db, index);
250 1095 tao
          }//else
251
        }//if
252
      }//for
253 1217 tao
    }//for
254 1095 tao
255
    //if couldn't get a connection, we should increase DBConnection pool
256
    //if the connection pool size is less than maximum connection number
257 1217 tao
258
    if ( size < MAXIMUMCONNECTIONNUMBER )
259 1095 tao
    {
260 1217 tao
       if ((size+INCREASECONNECTIONNUMBER) < MAXIMUMCONNECTIONNUMBER)
261 1095 tao
       {
262
         //if we can create INCREASECONNECTIONNUMBER of new DBConnection
263
         //add to connection pool
264
         for ( int i=0; i<INCREASECONNECTIONNUMBER; i++)
265
         {
266
           DBConnection dbConn = new DBConnection();
267
           connectionPool.add(dbConn);
268
         }//for
269
       }//if
270
       else
271
       {
272
         //There is no enough room to increase INCREASECONNECTIONNUMBER
273
         //we create new DBCoonection to Maximum connection number
274 1217 tao
         for (int i= size+1; i<= MAXIMUMCONNECTIONNUMBER; i++)
275 1095 tao
         {
276
           DBConnection dbConn = new DBConnection();
277
           connectionPool.add(dbConn);
278
         }//for
279
       }//else
280
281
    }//if
282
    else
283
    {
284 1217 tao
      /*throw new SQLException("The maximum of " +MAXIMUMCONNECTIONNUMBER +
285 1095 tao
                            " open db connections is reached." +
286
                            " New db connection to MetaCat" +
287 1217 tao
                            " cannot be established.");*/
288 2663 sgarg
       logMetacat.fatal("The maximum of " +MAXIMUMCONNECTIONNUMBER +
289 1089 tao
                            " open db connections is reached." +
290
                            " New db connection to MetaCat" +
291 2663 sgarg
                            " cannot be established.");
292 1849 tao
       countOfReachMaximum ++;
293
       if (countOfReachMaximum >= 10)
294 1217 tao
       {
295 1849 tao
         countOfReachMaximum =0;
296 2663 sgarg
         logMetacat.fatal("finally could not get dbconnection");
297 1849 tao
         return null;
298 1217 tao
       }
299 1849 tao
       else
300 1217 tao
       {
301 1849 tao
         //if couldn't get a connection, sleep 20 seconds and try again.
302
         try
303
         {
304 2663 sgarg
           logMetacat.info("sleep for could not get dbconnection");
305 1849 tao
           Thread.sleep(5000);
306
         }
307
         catch (Exception e)
308
        {
309 2663 sgarg
           logMetacat.error("Exception in getDBConnection" + e.getMessage());
310 1849 tao
        }
311
      }
312 1217 tao
313 1095 tao
314 1089 tao
    }//else
315
316
    //recursive to get new connection
317 1217 tao
    return getDBConnection(methodName);
318 1089 tao
  }//getDBConnection
319 1217 tao
320
321 1087 tao
322
323 1089 tao
  /**
324
   * Method to check if a db connection works fine or not
325
   * Check points include:
326
   * 1. check the usageCount if it is too many
327
   * 2. check the dbconne age if it is too old
328
   * 3. check the connection time if it is too long
329
   * 4. run simple sql query
330
   *
331
   * @param dbConn, the DBConnection object need to check
332
   */
333
  private static boolean validateDBConnection (DBConnection dbConn)
334
  {
335
336 1217 tao
337 1089 tao
    //Check if the DBConnection usageCount if it is too many
338
    if (dbConn.getUsageCount() >= MAXIMUMUSAGENUMBER )
339
    {
340 2663 sgarg
      logMetacat.debug("Connection usageCount is too many: "+
341
      dbConn.getUsageCount());
342 1089 tao
      return false;
343
    }
344
345
    //Check if the DBConnection has too much connection time
346
    if (dbConn.getConnectionTime() >= MAXIMUMCONNECTIONTIME)
347
    {
348 2663 sgarg
      logMetacat.debug("Connection has too much connection time: "+
349
      dbConn.getConnectionTime());
350 1089 tao
      return false;
351
    }
352
353
    //Check if the DBConnection is too old
354
    if (dbConn.getAge() >=MAXIMUMAGE)
355
    {
356 2663 sgarg
      logMetacat.debug("Connection is too old: "+dbConn.getAge());
357 1089 tao
      return false;
358
    }
359
360
    //Try to run a simple query
361
    try
362
    {
363
      long startTime=System.currentTimeMillis();
364 1217 tao
      DatabaseMetaData metaData = dbConn.getMetaData();
365 1089 tao
      long stopTime=System.currentTimeMillis();
366
      //increase one usagecount
367
      dbConn.increaseUsageCount(1);
368
      //increase connection time
369
      dbConn.setConnectionTime(stopTime-startTime);
370 1087 tao
371 1089 tao
    }
372
    catch (Exception e)
373
    {
374 2663 sgarg
      logMetacat.error("Error in validateDBConnection: "
375
                                +e.getMessage());
376 1089 tao
      return false;
377
    }
378
379
    return true;
380
381
  }//validateDBConnection()
382
383 1092 tao
  /**
384
   * Method to return a connection to DBConnection pool.
385
   * @param conn, the Connection object need to check in
386
   */
387 1122 tao
  public static synchronized void returnDBConnection(DBConnection conn,
388
                                                              int serialNumber)
389 1092 tao
  {
390
    int index = -1;
391
    DBConnection dbConn = null;
392
393
    index = getIndexOfPoolForConnection(conn);
394
    if ( index ==-1 )
395
    {
396 2663 sgarg
      logMetacat.info("Couldn't find a DBConnection in the pool"
397 1092 tao
                                  +" which have same tag to the returned"
398 2663 sgarg
                                  +" DBConnetion object");
399 1092 tao
      return;
400
401
    }//if
402
    else
403
    {
404 1122 tao
      //check the paramter - serialNumber which will be keep in calling method
405
      //if it is as same as the object's checkoutserial number.
406
      //if it is same return it. If it is not same, maybe the connection already
407
      // was returned ealier.
408 2663 sgarg
      logMetacat.debug("serial number in Connection: "
409
                                      +conn.getCheckOutSerialNumber());
410
      logMetacat.debug("serial number in local: "+serialNumber);
411 1122 tao
      if (conn.getCheckOutSerialNumber() == serialNumber)
412
      {
413
        dbConn = (DBConnection) connectionPool.elementAt(index);
414
        //set status to free
415
        dbConn.setStatus(FREE);
416
        //count connection time
417
        dbConn.setConnectionTime
418 1092 tao
                          (System.currentTimeMillis()-dbConn.getCheckOutTime());
419 1095 tao
420 1122 tao
        //set check out time to 0
421
        dbConn.setCheckOutTime(0);
422 1217 tao
423 2663 sgarg
        logMetacat.debug("Connection: "+dbConn.getTag()+" checked in.");
424
        logMetacat.debug("Connection: "+dbConn.getTag()+"'s status: "
425
                                                    +dbConn.getStatus());
426 1217 tao
427 1122 tao
      }//if
428 1217 tao
      else
429
      {
430 2663 sgarg
        logMetacat.info("This DBConnection couldn't return");
431 1217 tao
      }//else
432 1092 tao
    }//else
433
434
435
  }//returnConnection
436
437
  /**
438
   * Given a returned DBConnection, try to find the index of DBConnection object
439
   * in dbConnection pool by comparing DBConnection' tag and conn.toString.
440
   * If couldn't find , -1 will be returned.
441
   * @param conn, the connection need to be found
442
   */
443
  private static synchronized int getIndexOfPoolForConnection(DBConnection conn)
444
  {
445
    int index = -1;
446
    String info = null;
447 1217 tao
    //if conn is null return -1 too
448
    if (conn==null)
449
    {
450
      return -1;
451
    }
452 1092 tao
    //get tag of this returned DBConnection
453
    info = conn.getTag();
454
    //if the tag is null or empty, -1 will be returned
455
    if (info==null || info.equals(""))
456
    {
457
      return index;
458
    }
459
    //compare this info to the tag of every DBConnection in the pool
460
    for ( int i=0; i< connectionPool.size(); i++)
461
    {
462
      DBConnection dbConn = (DBConnection) connectionPool.elementAt(i);
463
      if (info.equals(dbConn.getTag()))
464
      {
465
        index = i;
466
        break;
467
      }//if
468
    }//for
469
470
    return index;
471
  }//getIndexOfPoolForConnection
472
473
  /**
474
   * Method to shut down all connections
475
   */
476
  public static void release()
477
  {
478
479
    //shut down the backgroud recycle thread
480 1095 tao
    if (DBCONNECTIONRECYCLETHREAD.equals("on"))
481
    {
482
      runner.interrupt();
483
    }
484 1092 tao
    //cose every dbconnection in the pool
485
    synchronized(connectionPool)
486
    {
487
      for (int i=0;i<connectionPool.size();i++)
488
      {
489
        try
490
        {
491
          DBConnection dbConn= (DBConnection) connectionPool.elementAt(i);
492
          dbConn.close();
493
        }//try
494
        catch (SQLException e)
495
        {
496 2663 sgarg
          logMetacat.error("Error in release connection: "
497
                                            +e.getMessage());
498 1092 tao
        }//catch
499
      }//for
500
    }//synchronized
501
  }//release()
502
503
  /**
504
   * periodically to recycle the connection
505
   */
506
  public void run()
507
  {
508
    DBConnection dbConn = null;
509
    //keep the thread running
510
    while (true)
511
    {
512
      //check every dbconnection in the pool
513
      synchronized(connectionPool)
514
      {
515
        for (int i=0; i<connectionPool.size(); i++)
516
        {
517
          dbConn = (DBConnection) connectionPool.elementAt(i);
518 1095 tao
519 1122 tao
          //if a DBConnection conncectioning time for one check out is greater
520
          //than 30000 milliseconds print it out
521
          if (dbConn.getStatus()==BUSY &&
522
            (System.currentTimeMillis()-dbConn.getCheckOutTime())>=30000)
523 1095 tao
          {
524 2663 sgarg
            logMetacat.fatal("This DBConnection is checked out for: "
525 1122 tao
            +(System.currentTimeMillis()-dbConn.getCheckOutTime())/1000
526 2663 sgarg
            +" secs");
527
            logMetacat.fatal(dbConn.getTag());
528
            logMetacat.error("method: "
529
                                          +dbConn.getCheckOutMethodName());
530 1095 tao
531
          }
532
533
          //check the validation of free connection in the pool
534 1092 tao
          if (dbConn.getStatus() == FREE)
535
          {
536
            try
537
            {
538
              //try to print out the warning message for every connection
539 1122 tao
              if (dbConn.getWarningMessage()!=null)
540
              {
541 2663 sgarg
                logMetacat.warn("Warning for connection "
542
                  +dbConn.getTag()+" : "+ dbConn.getWarningMessage());
543 1122 tao
              }
544 1092 tao
              //check if it is valiate, if not create new one and replace old one
545
              if (!validateDBConnection(dbConn))
546
              {
547 2663 sgarg
                logMetacat.debug("Recyle it: "+ dbConn.getTag());
548 1092 tao
                //close this DBConnection
549
                dbConn.close();
550
                //remove it form connection pool
551
                connectionPool.remove(i);
552
                //insert a new DBConnection to same palace
553
                dbConn = new DBConnection();
554
                connectionPool.insertElementAt(dbConn, i);
555 1122 tao
               }//if
556 1092 tao
            }//try
557
            catch (SQLException e)
558
            {
559 2663 sgarg
              logMetacat.error("Error in DBConnectionPool.run: "
560
                                              +e.getMessage());
561 1092 tao
            }//catch
562
          }//if
563
        }//for
564
      }//synchronize
565 1095 tao
      //Thread sleep
566 1092 tao
      try
567
      {
568 1095 tao
        Thread.sleep(CYCLETIMEOFDBCONNECTION);
569 1092 tao
      }
570
      catch (Exception e)
571
      {
572 2663 sgarg
        logMetacat.error("Error in DBConnectionPool.run: "
573
                                              +e.getMessage());
574 1092 tao
      }
575
    }//while
576
  }//run
577
578 1217 tao
  /**
579
   * Method to get the number of free DBConnection in DBConnection pool
580
   */
581 1219 tao
  public static synchronized int getFreeDBConnectionNumber()
582 1217 tao
  {
583
    int numberOfFreeDBConnetion = 0; //return number
584
    DBConnection db = null; //single DBconnection
585
    int poolSize = 0; //size of connection pool
586
    //get the size of DBConnection pool
587
    poolSize = connectionPool.size();
588
    //Check every DBConnection in the pool
589
    for ( int i=0; i<poolSize; i++)
590
    {
591
592
      db = (DBConnection) connectionPool.elementAt(i);
593
      //check the status of db. If it is free, count it
594
      if (db.getStatus() == FREE)
595
      {
596
        numberOfFreeDBConnetion++;
597
      }//if
598
    }//for
599
    //return the count result
600
    return numberOfFreeDBConnetion;
601
  }//getFreeDBConnectionNumber
602
603
   /**
604
   * Method to print out the method name which have busy DBconnection
605
   */
606
  public void printMethodNameHavingBusyDBConnection()
607
  {
608
609
    DBConnection db = null; //single DBconnection
610
    int poolSize = 0; //size of connection pool
611
    //get the size of DBConnection pool
612
    poolSize = connectionPool.size();
613
    //Check every DBConnection in the pool
614
    for ( int i=0; i<poolSize; i++)
615
    {
616
617
      db = (DBConnection) connectionPool.elementAt(i);
618
      //check the status of db. If it is free, count it
619
      if (db.getStatus() == BUSY)
620
      {
621 2663 sgarg
        logMetacat.warn("This method having a busy DBConnection: "
622
                                    +db.getCheckOutMethodName());
623
        logMetacat.warn("The busy DBConnection tag is: "
624
                                    +db.getTag());
625 1217 tao
      }//if
626
    }//for
627
628
  }//printMethodNameHavingBusyDBConnection
629
630 1219 tao
  /**
631
   * Method to decrease dbconnection pool size when all dbconnections are idle
632
   * If all connections are free and connection pool size greater than
633
   * initial value, shrink connection pool size to intital value
634
   */
635 1220 tao
  public static synchronized boolean shrinkConnectionPoolSize()
636 1219 tao
  {
637
     int connectionPoolSize = 0; //store the number of dbconnection pool size
638
     int freeConnectionSize = 0; //store the number of free dbconnection in pool
639
     int difference = 0; // store the difference number between connection size
640
                         // and free connection
641 1220 tao
     boolean hasException = false; //to check if has a exception happend
642
     boolean result = false; //result
643
     DBConnection conn = null; // the dbconnection
644 1219 tao
     connectionPoolSize = connectionPool.size();
645
     freeConnectionSize = getFreeDBConnectionNumber();
646 2716 sgarg
     difference = connectionPoolSize - freeConnectionSize;
647
648 2714 sgarg
     if(freeConnectionSize < connectionPoolSize){
649 2716 sgarg
    	 logMetacat.warn(difference + " connection(s) " +
650
                        "being used and connection pool size is " +connectionPoolSize);
651 2714 sgarg
     } else {
652
    	 logMetacat.info("Connection pool size: " +connectionPoolSize);
653
    	 logMetacat.info("Free Connection number: "+freeConnectionSize);
654
     }
655 1219 tao
656
     //If all connections are free and connection pool size greater than
657
     //initial value, shrink connection pool size to intital value
658
     if (difference == 0 && connectionPoolSize > INITIALCONNECTIONNUMBER)
659
     {
660 1220 tao
       //db connection having index from  to connectionpoolsize -1
661
       //intialConnectionnumber should be close and remove from pool
662
       for ( int i=connectionPoolSize-1; i >= INITIALCONNECTIONNUMBER ; i--)
663 1219 tao
       {
664 1220 tao
665 1219 tao
         //get the dbconnection from pool
666
         conn = (DBConnection) connectionPool.elementAt(i);
667
668
         try
669
         {
670 1220 tao
           //close conn
671 1219 tao
           conn.close();
672
         }//try
673
         catch (SQLException e)
674 1220 tao
         {
675
           // set hadException ture
676
           hasException = true;
677 2663 sgarg
           logMetacat.error("Couldn't close a DBConnection in " +
678 1220 tao
                            "DBConnectionPool.shrinkDBConnectionPoolSize: " +
679 2663 sgarg
                            e.getMessage());
680 1219 tao
         }//catch
681 1220 tao
682
        //remove it from pool
683
        connectionPool.remove(i);
684
        // becuase enter the loop, set result true
685
        result = true;
686 1219 tao
       }//for
687
     }//if
688 1220 tao
689
     //if hasException is true ( there at least once exception happend)
690
     // the result should be false
691
     if (hasException)
692
     {
693
       result =false;
694
     }//if
695
     // return result
696
     return result;
697 1219 tao
  }//shrinkDBConnectionPoolSize
698 1220 tao
699
    /**
700
   * Method to decrease dbconnection pool size when all dbconnections are idle
701
   * If all connections are free and connection pool size greater than
702
   * initial value, shrink connection pool size to intital value
703
   */
704
  public static synchronized void shrinkDBConnectionPoolSize()
705
  {
706
     int connectionPoolSize = 0; //store the number of dbconnection pool size
707
     int freeConnectionSize = 0; //store the number of free dbconnection in pool
708
     int difference = 0; // store the difference number between connection size
709
                         // and free connection
710
711
     DBConnection conn = null; // the dbconnection
712
     connectionPoolSize = connectionPool.size();
713
     freeConnectionSize = getFreeDBConnectionNumber();
714
     difference = connectionPoolSize - freeConnectionSize;
715 2716 sgarg
716
     if(freeConnectionSize < connectionPoolSize){
717
         logMetacat.warn(difference + " connection(s) " +
718
                        "being used and connection pool size is " +connectionPoolSize);
719
     } else {
720
         logMetacat.info("Connection pool size: " +connectionPoolSize);
721
         logMetacat.info("Free Connection number: "+freeConnectionSize);
722
     }
723 1219 tao
724 1220 tao
     //If all connections are free and connection pool size greater than
725
     //initial value, shrink connection pool size to intital value
726
     if (difference == 0 && connectionPoolSize > INITIALCONNECTIONNUMBER)
727
     {
728
       //db connection having index from  to connectionpoolsize -1
729
       //intialConnectionnumber should be close and remove from pool
730
       for ( int i=connectionPoolSize-1; i >= INITIALCONNECTIONNUMBER ; i--)
731
       {
732
733
         //get the dbconnection from pool
734
         conn = (DBConnection) connectionPool.elementAt(i);
735
         //make sure again the DBConnection status is free
736
         if (conn.getStatus()==FREE)
737
         {
738
           try
739
           {
740
             //close conn
741
             conn.close();
742
           }//try
743
           catch (SQLException e)
744
           {
745
746 2663 sgarg
             logMetacat.error("Couldn't close a DBConnection in " +
747 1220 tao
                            "DBConnectionPool.shrinkDBConnectionPoolSize: " +
748 2663 sgarg
                            e.getMessage());
749 1220 tao
           }//catch
750
751
           //remove it from pool
752
           connectionPool.remove(i);
753
         }//if
754
755
       }//for
756
     }//if
757
758
759
  }//shrinkDBConnectionPoolSize
760 1219 tao
761
762 1087 tao
}//DBConnectionPool