KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > uk > org > primrose > pool > core > Pool


1 /**
2 * Library name : Primrose - A Java Database Connection Pool.
3 * Published by Ben Keeping, http://primrose.org.uk .
4 * Copyright (C) 2004 Ben Keeping, primrose.org.uk
5 * Email: Use "Contact Us Form" on website
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */

21
22 package uk.org.primrose.pool.core;
23 import java.util.Vector JavaDoc;
24 import java.util.StringTokenizer JavaDoc;
25 import java.io.PrintWriter JavaDoc;
26 import java.io.Serializable JavaDoc;
27 import java.sql.SQLException JavaDoc;
28 import java.sql.Connection JavaDoc;
29
30 public class Pool implements Serializable JavaDoc {
31
32     public Pool() {}
33     /*****************************
34      ** Pool variables **
35      *****************************/

36
37     // The availability of the pool
38
private boolean available;
39     // The number of base connnections to have in the pool
40
private int base;
41     // The number of overflow connnections to have in the pool
42
private int overflow;
43     // The number of active overflow connnections to have in the pool
44
private int allowedOverflow;
45     // The name asscociated with this pool
46
private String JavaDoc name;
47     // Database connection variables
48
private String JavaDoc driverClass;
49     private String JavaDoc driverURL;
50     private String JavaDoc user;
51     private String JavaDoc password;
52     // The connections available for use in the pool
53
private Vector JavaDoc availableConnections = new Vector JavaDoc();
54     // The connections that are in use in the pool
55
private Vector JavaDoc activeConnectionsData = new Vector JavaDoc();
56     private Vector JavaDoc activeConnections = new Vector JavaDoc();
57     private Vector JavaDoc killedConnections = new Vector JavaDoc();
58     // The log
59
PrintWriter JavaDoc log;
60     // are there waiting threads
61
boolean waitingThreads = false;
62     // To log, or not to log. And if so, which type ?
63
private boolean messageLogging = false;
64     private boolean sizeLogging = false;
65     // How often we should cycle connections. -1 means we don't.
66
private int cycleConnections = -1;
67     boolean runPooledMode = true;
68     boolean connectionAutoCommit = true;
69     private int idleTime = 0;
70     // transaction level : -1 == do not alter current drivers state
71
private int connectionTransactionIsolation = -1;
72     // Optionall run a SQL string against a connection before handing it out
73
private String JavaDoc checkSQL = null;
74     public SyncHack synchack = new SyncHack();
75
76     /*****************************
77      ** Operational methods **
78      *****************************/

79     // Hmmmm... this really should be OK as sync'ing on 'this'
80
// but I'm not convinced.
81
// Use a cruddy hack sync class for now (2.7.0 bug fix)
82
class SyncHack {
83
84     }
85
86     /**
87     * Retrieve a connection from the pool.
88     */

89     public Connection JavaDoc get() {
90 synchronized(synchack) {
91         if (!runPooledMode) {
92             //PoolConnection pc = new PoolConnection(this).getConnection(driverClass, driverURL, user, password);
93
//pc.setConnectionCalled(true);
94
log("Getting new non-pooled connection " +this, false);
95             Connection JavaDoc pc = new NewConnection().get(driverClass, driverURL, user, password);
96             if (!checkConnection(pc)) {
97                 return null;
98             }
99
100             return pc;
101         }
102         // If there are connections in the base pool, then give out one of those
103
// but if there are none available, check that there are active connections
104
// - if there are none, then it means there are no base connections because
105
// they have been dumped by an idle-connection checker method. If this is the case,
106
// then return one of these, else check if there are any overflow connections to be
107
// be had. If not, then return null.
108
if (availableConnections.size() > 0 && isAvailable()) {
109             PoolConnection pc = (PoolConnection)availableConnections.elementAt(0);
110             availableConnections.removeElement(pc);
111             log("Extracting connection from pool " +pc, true);
112
113
114             // check the connection is OK (added 2.7.1)
115
// note that not all drivers really support this.
116
// for example, with MySQL, if you open a connection against a good db,
117
// and then the db crashes (and does not come back up), and then you ask if that connection is open
118
// this it reckons it is. Problem is - its not, so when you execute a transaction
119
// then it barfs, and leaves an 'active' connection in the pool
120
if (!checkConnection(pc)) {
121                 log("Connection " +pc + " was closed. Creating a new one.", true);
122                 // dump it
123
dump(pc);
124                 // fill the pool with a new connection
125
fill(1);
126                 // and recurse to extract a connection
127
return get();
128             }
129
130             activeConnectionsData.addElement(pc +"|" +System.currentTimeMillis());
131             activeConnections.addElement(pc);
132             pc.setConnectionCalled(true);
133
134             return pc;
135
136         } else if ((availableConnections.size() < base) && (activeConnections.size() < base) && isAvailable()) {
137             log("Extracting connection due to base being low due to idle connections", false);
138             if (fill(1)) { // if we managed to fill a connection, then get it, else db is down, so return null
139
return get();
140             } else {
141                 return null;
142             }
143
144         } else if (allowedOverflow > 0 && isAvailable()) {
145             log("Extracting connection by adding overflow ...", false);
146             fill(1);
147             // Decrement our allowedOverflow so that in heavy load, the pool
148
// doesn't run away with itself
149
allowedOverflow--;
150             return get();
151         } else {
152             return null;
153         }
154 }
155     }
156
157     public boolean checkConnection(Connection JavaDoc pc) {
158         try {
159             if (pc.isClosed()) return false;
160         } catch (SQLException JavaDoc e) {
161             log("Error calling isClosed() on connection " +pc +" : " +e, false);
162             return false;
163         }
164         // Only run a check if they want it
165
if (checkSQL != null) {
166
167             java.sql.Statement JavaDoc s = null;
168             java.sql.ResultSet JavaDoc rs = null;
169             try {
170                 s = pc.createStatement();
171                 rs = s.executeQuery(checkSQL);
172             } catch (Exception JavaDoc e) {
173                 log("SQL Check returned an error - dumping this connection(" +pc +"). Error was : " +e, false);
174                 return false;
175             } finally {
176                 try {
177                     if (rs != null) rs.close();
178                     if (s != null) s.close();
179                 } catch (java.sql.SQLException JavaDoc sqle) {/*don't care*/}
180             }
181         }
182
183         return true;
184     }
185
186     /**
187     * Add a connection to the pool
188     */

189     public boolean fill(int num) {
190         for (int i = 0; i < num; i++) {
191             PoolConnection pc = new PoolConnection(this).getConnection(driverClass, driverURL, user, password);
192             if (pc != null) {
193                 if (checkConnection(pc)) {
194                     // check & set the defaults
195
setConnectionDefaults(pc);
196                     availableConnections.addElement(pc);
197                     log("Filled pool with connection " +pc, true);
198                 } else {
199                     log("New Connection was closed or broken ! Perhaps the database is down ?", true);
200                 return false;
201                 }
202             } else {
203                 log("New Connection was NULL ! Perhaps the database is down ?", true);
204                 return false;
205             }
206         }
207         return true;
208     }
209
210
211     /**
212     * Replace a connection into the pool.
213     */

214     public void put(PoolConnection pc) {
215 synchronized(synchack) {
216
217         if (!runPooledMode) {
218             log("Closing non-pooled connection " +this, false);
219             dump(pc, true);
220             return;
221         }
222         boolean dumped = false;
223
224         // Check for killed connections.
225
// If they are here, then they should be closed, but if not, close them
226
// Return afterwards, so we don't replace the connection with another one
227
// as this should already have been done in the kill method.
228
if (killedConnections.contains(pc)) {
229             // recursive error fixed in 2.4.6a
230
// if (pc != null && !(pc.isClosed())) dump(pc, false);
231
// pc = null;
232
// killedConnections.remove(pc);
233
return;
234         }
235
236         // Don't add null or closed connections back
237
if (pc != null && (!pc.isClosed())) {
238             // remove it from the active list
239
removeFromActiveConnections(pc);
240             // If we have cycing of connections on
241
// and the number of SQL calls/transactions is greater
242
// than the set limit, then don;t add the connection into the pool
243
if (getCycleConnections() != -1 && pc.getNumberOfCalls() >= getCycleConnections()) {
244                 log("Cycled connection " +pc +" after numberOfCalls(" +pc.getNumberOfCalls() +")", false);
245                 dump(pc);
246                 removeFromActiveConnections(pc);
247
248                 pc = new PoolConnection(this).getConnection(driverClass, driverURL, user, password);
249             }
250
251             // Dump overflow connections, becasue we don't want to return them to
252
// the base pool
253
// waitingThreads is controlled by the Pool.java wrapper (ie Queue.java).
254

255             //if (availableConnections.size() >= base && !waitingThreads) {
256
// This hack trys to constrain the number of connections to the preset limits.
257
// I've found that under heavy load (100's of threads queueing)
258
// there is a thread concurrency issue where that if you kill connections via the daemon
259
// it sometimes breaks the limit (ie issues 21 available connections
260
// when the overflow + base is only 20).
261
// I cannot find the bug, after days of trying.
262
// This may come back to bite me in the ass, but it seems to work for now.
263
// The original 'if' is above ...
264

265             if (availableConnections.size() + activeConnections.size() > base +overflow) {
266                 //removeFromActiveConnections(pc);
267
dump(pc, true);
268                 return;
269
270             }
271
272             // temper the overflow
273
if (allowedOverflow > overflow) allowedOverflow--;
274
275             if (availableConnections.size() >= base && !waitingThreads) {
276                 //System.err.println("Dumping overflow : " +waitingThreads +" " +allowedOverflow);
277
dumped = true;
278                 dump(pc, true);
279                 allowedOverflow++;
280             // Return the connection to the base pool
281
} else {
282                 dumped = false;
283                 //availableConnections.addElement(pc);
284
availableConnections.insertElementAt(pc, 0);
285
286             }
287         // If the connection is duff, get a new one (unless the base is full)
288
} else {
289             if (availableConnections.size() < base) {
290                 log("Replacing duff connecion (" +pc +") with new one ..", true);
291                 fill(1);
292             }
293         }
294
295
296         if (!dumped) {
297             // check & set the defaults
298
setConnectionDefaults(pc);
299             log("Put connection into pool " +pc, true);
300         } else {
301             log("Dumped connection " +pc +" " +waitingThreads, true);
302         }
303 }
304      }
305
306
307     /**
308     * Apply default connection properties to the connection
309     * Called from fill() when a brand new connection is added to the pool,
310     * and from put() when a connection is returned to the pool
311     */

312     public void setConnectionDefaults(PoolConnection pc) {
313             // set the default auto commit value
314
try {
315                 if (pc.getAutoCommit() != connectionAutoCommit) {
316                     // don't log changes to driver defaults if the connection
317
// is brand new
318
if (pc.getNumberOfCalls() > 1) {
319                         log("WARNING : Checking autocommit value : Looks like someone has changed it from the default, and has not set it back. Default should be '" +connectionAutoCommit +"', but the connection value is '" +pc.getAutoCommit() +"'", false);
320                     }
321                     pc.setAutoCommit(connectionAutoCommit);
322
323                 }
324             } catch (SQLException JavaDoc sqle) {
325                 sqle.printStackTrace(System.err);
326             }
327
328
329             try {
330                 // set the default transaction isolation level
331
// if it is -1, then set the default
332
if (connectionTransactionIsolation == -1) {
333                     setConnectionTransactionIsolation(null);
334                 }
335                 // if the connections setting does not equal the pool's,
336
// then set it (and log that somone changed it, but did not set it back
337
if (pc.getTransactionIsolation() != connectionTransactionIsolation) {
338                     // don't log changes to driver defaults if the connection
339
// is brand new
340
if (pc.getNumberOfCalls() > 1) {
341                         log("WARNING : Checking transaction isolation level : Looks like someone has changed it from the default, and has not set it back. Default should be '" +getConnectionTransactionIsolation() +"', but the connection value is '" +getConnectionTransactionIsolation(pc.getTransactionIsolation()) +"'", false);
342                     }
343                     pc.setTransactionIsolation(connectionTransactionIsolation);
344                 }
345             } catch (SQLException JavaDoc sqle) {
346                 sqle.printStackTrace(System.err);
347             }
348     }
349
350     public void killActiveConnection(PoolConnection pc) {
351         //System.err.println("kill active connections ... " +waitingThreads +" " +availableConnections.size() +" " +pc);
352

353         // Lock this thread so that no-one can return this
354
// object to the pool before we add it to the killedConnections list
355
synchronized(this) {
356             removeFromActiveConnections(pc);
357             killedConnections.addElement(pc);
358
359         }
360
361         // Close the connection
362
dump(pc, false);
363
364         // remove the connection from the killed connections list
365
killedConnections.removeElement(pc);
366
367         // Replace the connection with a new one
368
pc = new PoolConnection(this).getConnection(driverClass, driverURL, user, password);
369         put(pc);
370         //fill(1);
371

372     }
373
374     public void dumpIdleConnection(PoolConnection pc) {
375             availableConnections.removeElement(pc);
376             log(pc +" Dumping IDLE connection, idle for " +(pc.getIdleTime() /1000) +" seconds", false);
377             try {
378                 synchronized (pc) {
379                     pc.getRealConnection().close();
380                 }
381             } catch (SQLException JavaDoc sqle) {
382                 sqle.printStackTrace(System.err);
383             }
384             pc = null;
385             if (availableConnections.size() >= base) allowedOverflow++;
386     }
387
388     public void removeFromActiveConnections(PoolConnection pc) {
389         boolean found = false;
390          for (int i = 0; i < activeConnectionsData.size(); i++) {
391              if (new StringTokenizer JavaDoc((String JavaDoc)activeConnectionsData.get(i), "|").nextToken().equals("" +pc)) {
392                 activeConnectionsData.removeElement(activeConnectionsData.get(i));
393                 activeConnections.removeElement(pc);
394                 found = true;
395              }
396          }
397         if (!found) log("[Pool::removeFromActiveConnections] Could not find " +pc +" to remove from active list !", false);
398     }
399
400     /**
401     * Dump a connection and close the wrapped Connection object
402     */

403     public void dump(PoolConnection pc) {
404         dump(pc, true);
405     }
406
407
408     public void dump(PoolConnection pc, boolean nullify) {
409         if (pc == null) return;
410
411         if (!pc.isClosed()) {
412             try {
413                 synchronized(pc) {
414                     if (runPooledMode) {
415                         pc.close(false);
416                     }
417
418                     java.sql.Connection JavaDoc c = pc.getRealConnection();
419                     if (c != null) {
420                         c.close();
421                     }
422                 }
423             } catch (SQLException JavaDoc sqle) {
424                 sqle.printStackTrace(System.err);
425             }
426             if (nullify) pc = null;
427         }
428     }
429
430     public void log(String JavaDoc message, boolean printSize) {
431         // They may not want to log things :)
432
if (log == null) return;
433
434         if (messageLogging) {
435             //System.err.println("[Pool-" +name +"@" +sid +"] " +message);
436
//System.err.println("[Pool-" +name +"@" +driverURL +"] " +message);
437
//log.println("[Pool-" +name +"@" +sid +"] " +message +" " +new java.util.Date());
438
log.println("[Pool-" +name +"@" +driverURL+"] " +message +" " +new java.util.Date JavaDoc());
439             log.flush();
440         }
441
442         if (sizeLogging) {
443             if (printSize) {
444                 //System.err.println("[Pool-" +name +"@" +driverURL +"] [available(" +availableConnections.size() +"), active(" +activeConnections.size() +"), overflow("+ allowedOverflow+")]");
445
log.println("[Pool-" +name +"] [available(" +availableConnections.size() +"), active(" +activeConnections.size() +"), overflow("+ allowedOverflow+")]"); //, waitingThreads(" +waitingThreads +")]");
446

447                 //System.err.println("[Pool-" +name +"@" +sid +"] [available(" +availableConnections.size() +"), active(" +activeConnections.size() +"), overflow("+ allowedOverflow+")]");
448
//log.println("[Pool] [available(" +availableConnections.size() +"), active(" +activeConnections.size() +"), overflow("+ allowedOverflow+")]");
449

450             }
451             log.flush();
452         }
453
454
455     }
456
457
458     /*****************************
459      ** Mutators and Accessors **
460      *****************************/

461
462     public boolean getRunPooledMode() {
463         return runPooledMode;
464     }
465
466     /**
467     * Returns the sizeLogging state.
468     * @return boolean
469     */

470     public boolean getSizeLogging() {
471         return this.sizeLogging;
472     }
473
474     /**
475     * Returns the messageLogging state.
476     * @return boolean
477     */

478     public boolean getMessageLogging() {
479         return this.messageLogging;
480     }
481
482     /**
483     * Returns the waitingThreads.
484     * @return boolean
485     */

486     public boolean getWaitingThreads() {
487         return waitingThreads;
488     }
489
490     /**
491     * Returns the log.
492     * @return PrintWriter
493     */

494     public PrintWriter JavaDoc getLog() {
495         return log;
496     }
497
498     /**
499     * Returns the active.
500     * @return boolean
501     */

502     public boolean isAvailable() {
503         return available;
504     }
505
506     /**
507     * Returns the activeConnectionsData.
508     * @return Vector
509     */

510     public Vector JavaDoc getActiveConnections() {
511         return activeConnections;
512     }
513
514     /**
515     * Returns the activeConnectionsData.
516     * @return Vector
517     */

518     public String JavaDoc[] getActiveConnectionsData() {
519 synchronized(synchack) {
520 // Vector activeConnections = pool.getActiveConnections();
521
// Vector activeConnectionsData = pool.getActiveConnectionsData();
522

523         String JavaDoc[] s = new String JavaDoc[activeConnections.size()];
524         for (int i = 0; i < activeConnections.size(); i++) {
525             PoolConnection pc = (PoolConnection)activeConnections.get(i);
526 // StringTokenizer st = new StringTokenizer((String)activeConnectionsData.get(i), "|");
527
// st.nextToken();
528
StringTokenizer JavaDoc st1 = new StringTokenizer JavaDoc("" +pc, "@");
529             st1.nextToken();
530 // s[i] = ("ID(" +st1.nextToken() +"), SQL(" +pc.getSql() +"), TIME(" +((System.currentTimeMillis() - (Long.parseLong(st.nextToken()))) /1000) +" secs), CALLER(" +pc.getCaller() +"), NUMBER_OF_CALLS(" + pc.getNumberOfCalls()+")");
531
s[i] = ("ID(" +st1.nextToken() +"), SQL(" +pc.getSql() +"), TIME(" +(pc.getTimeInUse() / 1000.0)+" secs), CALLER(" +pc.getCaller() +"), NUMBER_OF_CALLS(" + pc.getNumberOfCalls()+")");
532
533
534         }
535
536         return s;
537 }
538     }
539
540     /**
541     * Returns the availableConnections.
542     * @return Vector
543     */

544     public String JavaDoc[] getAvailableConnections() {
545 synchronized(synchack) {
546 // Vector availableConnections = pool.getAvailableConnections();
547
String JavaDoc[] s = new String JavaDoc[availableConnections.size()];
548         for (int i = 0; i < availableConnections.size(); i++) {
549             PoolConnection pc = (PoolConnection)availableConnections.get(i);
550             StringTokenizer JavaDoc st1 = new StringTokenizer JavaDoc("" +pc, "@");
551             st1.nextToken();
552             s[i] = ("ID(" +st1.nextToken() +"), IDLE_FOR(" +(pc.getIdleTime() /1000) +" seconds), NUMBER_OF_CALLS(" + pc.getNumberOfCalls()+")");
553         }
554         return s;
555 }
556     }
557
558     /**
559     * Returns the base.
560     * @return int
561     */

562     public int getBase() {
563         return base;
564     }
565
566     /**
567     * Returns the name.
568     * @return String
569     */

570     public String JavaDoc getName() {
571         return name;
572     }
573
574     /**
575     * Returns the overflow.
576     * @return int
577     */

578     public int getOverflow() {
579         return overflow;
580     }
581
582     /**
583     * Returns the password.
584     * @return String
585     */

586     public String JavaDoc getPassword() {
587         return password;
588     }
589
590     /**
591     * Returns the driverClass.
592     * @return String
593     */

594     public String JavaDoc getDriverClass() {
595         return driverClass;
596     }
597
598     /**
599     * Returns the driverURL.
600     * @return String
601     */

602     public String JavaDoc getDriverURL() {
603         return driverURL;
604     }
605
606     /**
607     * Returns the user.
608     * @return String
609     */

610     public String JavaDoc getUser() {
611         return this.user;
612     }
613
614     /**
615     * Gets how often the pool should cycle connections.
616     * The param is the number of SQL transactions performed.
617     * If -1, then connections are not cycled.
618     */

619     public int getCycleConnections() {
620         return this.cycleConnections;
621     }
622
623     /**
624     * Gets whether or not connections should default to having auto commit turned on or off.
625     */

626     public boolean getConnectionAutoCommit() {
627         return this.connectionAutoCommit;
628     }
629
630     public String JavaDoc getCheckSQL() {
631         return this.checkSQL;
632     }
633
634     public void setCheckSQL(String JavaDoc checkSQL) {
635         this.checkSQL = checkSQL;
636     }
637
638     public void setRunPooledMode(boolean runPooledMode) {
639         /* log("INFO ! Setting runPooledMode(" +runPooledMode +")", false);
640             if (runPooledMode) {
641                 log("\tNow running WITH pooling ...", false);
642             } else {
643                 log("\tNow running WITHOUT pooling ...", false);
644             }
645         */

646             this.runPooledMode = runPooledMode;
647     }
648
649     /**
650     * Sets how often the pool should cycle connections.
651     * The param is the number of SQL transactions performed.
652     * If -1, then connections are not cycled.
653     */

654     public void setCycleConnections(int cycleConnections) {
655         this.cycleConnections = cycleConnections;
656     }
657
658
659     /**
660     * Sets whether the pool logs messages/actions.
661     */

662     public void setMessageLogging(boolean messageLogging) {
663         this.messageLogging = messageLogging;
664     }
665
666     /**
667     * Sets whether the pool logs the size of the pool.
668     */

669     public void setSizeLogging(boolean sizeLogging) {
670         this.sizeLogging = sizeLogging;
671     }
672
673     /**
674     * Sets the log.
675     * @param log The log to set
676     */

677     public void setLog(PrintWriter JavaDoc log) {
678         this.log = log;
679     }
680
681     /**
682     * Sets the waitingThreads.
683     * @param waitingThreads The waitingThreads to set
684     */

685     public void setWaitingThreads(boolean waitingThreads) {
686         this.waitingThreads = waitingThreads;
687     }
688
689     /**
690     * Sets the active.
691     * @param active The active to set
692     */

693     public void setAvailable(boolean available) {
694         this.available = available;
695     }
696
697     /**
698     * Sets the activeConnectionsData.
699     * @param activeConnectionsData The activeConnectionsData to set
700     */

701     public void setActiveConnections(Vector JavaDoc activeConnectionsData) {
702         this.activeConnectionsData = activeConnectionsData;
703     }
704
705     /**
706     * Sets the availableConnections.
707     * @param availableConnections The availableConnections to set
708     */

709     public void setAvailableConnections(Vector JavaDoc availableConnections) {
710         this.availableConnections = availableConnections;
711     }
712
713     /**
714     * Sets the base.
715     * @param base The base to set
716     */

717     public void setBase(int base) {
718         this.base = base;
719     }
720
721
722     /**
723     * Sets the name.
724     * @param name The name to set
725     */

726     public void setName(String JavaDoc name) {
727         this.name = name;
728     }
729
730     /**
731     * Sets the overflow.
732     * @param overflow The overflow to set
733     */

734     public void setOverflow(int overflow) {
735         this.overflow = overflow;
736         this.allowedOverflow = overflow;
737     }
738
739     /**
740     * Sets the password.
741     * @param password The password to set
742     */

743     public void setPassword(String JavaDoc password) {
744         this.password = password;
745     }
746
747     /**
748     * Sets the driverURL.
749     * @param driverURL The driverURL to set
750     */

751     public void setDriverURL(String JavaDoc driverURL) {
752         this.driverURL = driverURL;
753     }
754
755     /**
756     * Sets the driverClass.
757     * @param driverClass The driverClass to set
758     */

759     public void setDriverClass(String JavaDoc driverClass) {
760         this.driverClass = driverClass;
761     }
762
763     /**
764     * Sets the user.
765     * @param user The user to set
766     */

767     public void setUser(String JavaDoc user) {
768         this.user = user;
769     }
770
771     /**
772     * Sets whether or not connections should default to having auto commit turned on or off.
773     * The value is applied each time a new connection is extracted from the pool, if the current value
774     * on the connection is different to this.
775     */

776     public void setConnectionAutoCommit(boolean connectionAutoCommit) {
777         this.connectionAutoCommit = connectionAutoCommit;
778     }
779
780
781     /**
782     * Sets the default level for connection's isolation transaction level.
783     * This can only be set on startup - not during runtime.
784     */

785     public void setConnectionTransactionIsolation(String JavaDoc sConnectionTransactionIsolation) {
786         // If not specified in the config file, then use the driver's default
787
if (sConnectionTransactionIsolation == null) {
788             try {
789                 Connection JavaDoc c = new NewConnection().get(driverClass, driverURL, user, password);
790                 // if the connection is null, then it means the db is down or not reachable
791
// so don't go any further.
792
// If this is the case, the when the db comes back up
793
// the transaction isolation level will -1, and the next 'get' on the Pool
794
// will cause this code to be run again to default the level if needs be.
795
if (c == null) {
796                     log("WARNING : DB is down/not reachable, and because the pool config variable 'connectionTransactionLevel' is not set, it will be set when the db comes back up and the next call for a connection is made.", false);
797                     connectionTransactionIsolation = -1;
798                     return;
799                 }
800                 connectionTransactionIsolation = c.getTransactionIsolation();
801                 c.close();
802             } catch (SQLException JavaDoc sqle) {
803
804                 sqle.printStackTrace(System.err);
805             }
806         } else if (sConnectionTransactionIsolation.equalsIgnoreCase("TRANSACTION_NONE")) {
807             connectionTransactionIsolation = Connection.TRANSACTION_NONE;
808         } else if (sConnectionTransactionIsolation.equalsIgnoreCase("TRANSACTION_READ_COMMITTED")) {
809             connectionTransactionIsolation = Connection.TRANSACTION_READ_COMMITTED;
810         } else if (sConnectionTransactionIsolation.equalsIgnoreCase("TRANSACTION_READ_UNCOMMITTED")) {
811             connectionTransactionIsolation = Connection.TRANSACTION_READ_UNCOMMITTED;
812         } else if (sConnectionTransactionIsolation.equalsIgnoreCase("TRANSACTION_REPEATABLE_READ")) {
813             connectionTransactionIsolation = Connection.TRANSACTION_REPEATABLE_READ;
814         } else if (sConnectionTransactionIsolation.equalsIgnoreCase("TRANSACTION_SERIALIZABLE")) {
815             connectionTransactionIsolation = Connection.TRANSACTION_SERIALIZABLE;
816         // If not recognized, then use the driver's default
817
} else {
818             log("WARNING : setConnectionTransactionIsolation : Do not recognize transaction level of '" +sConnectionTransactionIsolation +"', using driver default", false);
819             try {
820                 Connection JavaDoc c = new NewConnection().get(driverClass, driverURL, user, password);
821                 connectionTransactionIsolation = c.getTransactionIsolation();
822                 c.close();
823             } catch (SQLException JavaDoc sqle) {
824
825                 sqle.printStackTrace(System.err);
826             }
827         }
828
829         log("INFO : setConnectionTransactionIsolation : Set connection transaction level to '" +getConnectionTransactionIsolation() +"'", false);
830
831     }
832
833     /**
834     * Gets the default level for connection's isolation transaction level.
835     */

836     public String JavaDoc getConnectionTransactionIsolation() {
837         return getConnectionTransactionIsolation(connectionTransactionIsolation);
838     }
839
840     private String JavaDoc getConnectionTransactionIsolation(int level) {
841         String JavaDoc sLevel = "DRIVER_DEFAULT";
842
843         switch (level) {
844             case Connection.TRANSACTION_NONE :
845                 sLevel = "TRANSACTION_NONE";
846                 break;
847             case Connection.TRANSACTION_READ_COMMITTED :
848                 sLevel = "TRANSACTION_READ_COMMITTED";
849                 break;
850             case Connection.TRANSACTION_READ_UNCOMMITTED :
851                 sLevel = "TRANSACTION_READ_UNCOMMITTED";
852                 break;
853             case Connection.TRANSACTION_REPEATABLE_READ :
854                 sLevel = "TRANSACTION_REPEATABLE_READ";
855                 break;
856             case Connection.TRANSACTION_SERIALIZABLE :
857                 sLevel = "TRANSACTION_SERIALIZABLE";
858                 break;
859         }
860
861         return sLevel;
862     }
863
864
865
866     /**
867     * If the pool connections are too idle, then we may as well dump
868     * them as they may go stale, nad there is no point in keeping
869     * a network connection open if we don't need it.
870     */

871     public int checkIdleConnections() {
872 synchronized(synchack) {
873 // Vector availableConnections = pool.getAvailableConnections();
874
PoolConnection[] pca = new PoolConnection[availableConnections.size()];
875         for (int i = 0; i < availableConnections.size(); i++) {
876             pca[i] = (PoolConnection)availableConnections.elementAt(i);
877         }
878
879         for (int i = 0; i < pca.length; i++) {
880             PoolConnection pc = pca[i];
881             if (pc.getIdleTime() > this.getIdleTime()) {
882                 dumpIdleConnection(pc);
883             }
884         }
885         pca = null;
886         return 0;
887     }
888 }
889
890     /**
891     * Gets the pool idle time.
892     */

893     public int getIdleTime() {
894         return this.idleTime;
895     }
896
897     /**
898     * Sets the pool idle time.
899     */

900     public void setIdleTime(int idleTime) {
901         this.idleTime = idleTime;
902     }
903
904 }
Popular Tags