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