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