Source Code Cross Referenced for JDCConnectionPool.java in  » Groupware » hipergate » com » knowgate » jdc » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Groupware » hipergate » com.knowgate.jdc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:          Copyright (C) 2003  Know Gate S.L. All rights reserved.
0003:                              C/Oņa, 107 1š2 28050 Madrid (Spain)
0004:
0005:          Redistribution and use in source and binary forms, with or without
0006:          modification, are permitted provided that the following conditions
0007:          are met:
0008:
0009:          1. Redistributions of source code must retain the above copyright
0010:             notice, this list of conditions and the following disclaimer.
0011:
0012:          2. The end-user documentation included with the redistribution,
0013:             if any, must include the following acknowledgment:
0014:             "This product includes software parts from hipergate
0015:             (http://www.hipergate.org/)."
0016:             Alternately, this acknowledgment may appear in the software itself,
0017:             if and wherever such third-party acknowledgments normally appear.
0018:
0019:          3. The name hipergate must not be used to endorse or promote products
0020:             derived from this software without prior written permission.
0021:             Products derived from this software may not be called hipergate,
0022:             nor may hipergate appear in their name, without prior written
0023:             permission.
0024:
0025:          This library is distributed in the hope that it will be useful,
0026:          but WITHOUT ANY WARRANTY; without even the implied warranty of
0027:          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
0028:
0029:          You should have received a copy of hipergate License with this code;
0030:          if not, visit http://www.hipergate.org or mail to info@hipergate.org
0031:         */
0032:
0033:        package com.knowgate.jdc;
0034:
0035:        import java.util.HashMap;
0036:        import java.util.Iterator;
0037:        import java.util.LinkedList;
0038:        import java.util.ListIterator;
0039:        import java.util.Set;
0040:        import java.util.Vector;
0041:        import java.util.Enumeration;
0042:        import java.util.Date;
0043:        import java.util.ConcurrentModificationException;
0044:
0045:        import java.sql.DriverManager;
0046:        import java.sql.Connection;
0047:        import java.sql.CallableStatement;
0048:        import java.sql.PreparedStatement;
0049:        import java.sql.SQLException;
0050:        import java.sql.Timestamp;
0051:        import java.sql.Types.*;
0052:
0053:        import com.knowgate.debug.DebugFile;
0054:
0055:        /**
0056:         * <p>Connection pool daemon thread</p>
0057:         * This thread scans a ConnectionPool every given interval calling
0058:         * ConnectionPool.reapConnections() for closing unused connections.
0059:         */
0060:
0061:        final class ConnectionReaper extends Thread {
0062:
0063:            /**
0064:             * Reference to reaped connection pool
0065:             */
0066:            private JDCConnectionPool pool;
0067:
0068:            /**
0069:             * Used to stop the Connection reaper thread
0070:             */
0071:            private boolean keepruning;
0072:
0073:            /**
0074:             * Connection Reaper call interval (default = 5 mins)
0075:             */
0076:            private long delay = 300000l;
0077:
0078:            /**
0079:             * <p>Constructor</p>
0080:             * @param forpool JDCConnectionPool
0081:             */
0082:            ConnectionReaper(JDCConnectionPool forpool) {
0083:                pool = forpool;
0084:                keepruning = true;
0085:                try {
0086:                    checkAccess();
0087:                    setDaemon(true);
0088:                    setPriority(MIN_PRIORITY);
0089:                } catch (SecurityException ignore) {
0090:                }
0091:            }
0092:
0093:            /**
0094:             * Get connection reaper call interval
0095:             * @return long Number of miliseconds between reaper calls
0096:             * @since 3.0
0097:             */
0098:            public long getDelay() {
0099:                return delay;
0100:            }
0101:
0102:            /**
0103:             * <p>Set connection reaper call interval</p>
0104:             * The default value is 5 minutes
0105:             * @param lDelay long Number of miliseconds between reaper calls
0106:             * @throws IllegalArgumentException if lDelay is less than 1000
0107:             * @since 3.0
0108:             */
0109:            public void setDelay(long lDelay) throws IllegalArgumentException {
0110:                if (lDelay < 1000l)
0111:                    throw new IllegalArgumentException(
0112:                            "ConnectionReaper delay cannot be smaller than 1000 miliseconds");
0113:                delay = lDelay;
0114:            }
0115:
0116:            public void halt() {
0117:                keepruning = false;
0118:            }
0119:
0120:            /**
0121:             * Reap connections every n-minutes
0122:             */
0123:            public void run() {
0124:                while (keepruning) {
0125:                    try {
0126:                        sleep(delay);
0127:                    } catch (InterruptedException e) {
0128:                    }
0129:                    pool.reapConnections();
0130:                } // wend
0131:            } // run
0132:        } // ConnectionReaper
0133:
0134:        // ---------------------------------------------------------
0135:
0136:        /**
0137:         * <p>JDBC Connection Pool</p>
0138:         * <p>Implementation of a standard JDBC connection pool.</p>
0139:         * @version 2.2
0140:         */
0141:
0142:        public final class JDCConnectionPool {
0143:
0144:            private Object binding;
0145:            private Vector connections;
0146:            private int openconns;
0147:            private HashMap callers;
0148:            private String url, user, password;
0149:            private ConnectionReaper reaper;
0150:            private LinkedList errorlog;
0151:
0152:            /**
0153:             * Staled connection threshold (10 minutes)
0154:             * The maximum time that any SQL single statement may last.
0155:             */
0156:            private long timeout = 600000l;
0157:
0158:            /**
0159:             * Soft limit for maximum open connections
0160:             */
0161:            private int poolsize = 32;
0162:
0163:            /**
0164:             * Hard absolute limit for maximum open connections
0165:             */
0166:            private int hardlimit = 100;
0167:
0168:            // ---------------------------------------------------------
0169:
0170:            /**
0171:             * Constructor
0172:             * By default, maximum pool size is set to 32,
0173:             * maximum opened connections is 100,
0174:             * login timeout is 20 seconds,
0175:             * connection timeout is 5 minutes.
0176:             * @param url JDBC URL string
0177:             * @param user Database user
0178:             * @param password Password for user
0179:             */
0180:
0181:            public JDCConnectionPool(String url, String user, String password) {
0182:
0183:                binding = null;
0184:
0185:                if (null == url)
0186:                    throw new IllegalArgumentException(
0187:                            "JDCConnectionPool : url cannot be null");
0188:
0189:                if (url.length() == 0)
0190:                    throw new IllegalArgumentException(
0191:                            "JDCConnectionPool : url value not set");
0192:
0193:                this .url = url;
0194:                this .user = user;
0195:                this .password = password;
0196:                this .openconns = 0;
0197:
0198:                DriverManager.setLoginTimeout(20); // default login timeout = 20 seconds
0199:
0200:                connections = new Vector(poolsize <= hardlimit ? poolsize
0201:                        : hardlimit);
0202:                reaper = new ConnectionReaper(this );
0203:                reaper.start();
0204:
0205:                if (DebugFile.trace)
0206:                    callers = new HashMap(1023);
0207:
0208:                errorlog = new LinkedList();
0209:            }
0210:
0211:            // ---------------------------------------------------------
0212:
0213:            /**
0214:             * <p>Constructor</p>
0215:             * This method sets a default login timeout of 20 seconds
0216:             * @param bind DBBind owner of the connection pool (may be <b>null</b>)
0217:             * @param url JDBC URL string
0218:             * @param user Database user
0219:             * @param password Password for user
0220:             * @param maxpoolsize Maximum pool size
0221:             * @param maxconnections Maximum opened connections
0222:             * @param connectiontimeout Maximum time that a
0223:             * @param logintimeout Maximum time, in seconds, to wait for connection
0224:             * @since v2.2
0225:             */
0226:
0227:            public JDCConnectionPool(Object bind, String url, String user,
0228:                    String password, int maxpoolsize, int maxconnections,
0229:                    int logintimeout, long connectiontimeout) {
0230:
0231:                binding = bind;
0232:
0233:                if (null == url)
0234:                    throw new IllegalArgumentException(
0235:                            "JDCConnectionPool : url cannot be null");
0236:
0237:                if (url.length() == 0)
0238:                    throw new IllegalArgumentException(
0239:                            "JDCConnectionPool : url value not set");
0240:
0241:                if (maxpoolsize < 1)
0242:                    throw new IllegalArgumentException(
0243:                            "maxpoolsize must be greater than or equal to 1");
0244:
0245:                if (maxconnections < 1)
0246:                    throw new IllegalArgumentException(
0247:                            "maxpoolsize must be greater than or equal to 1");
0248:
0249:                if (maxpoolsize > maxconnections)
0250:                    throw new IllegalArgumentException(
0251:                            "maxpoolsize must be less than or equal to maxconnections");
0252:
0253:                this .url = url;
0254:                this .user = user;
0255:                this .password = password;
0256:                this .openconns = 0;
0257:                this .poolsize = maxpoolsize;
0258:                this .hardlimit = maxconnections;
0259:                this .timeout = connectiontimeout;
0260:
0261:                DriverManager.setLoginTimeout(logintimeout);
0262:
0263:                connections = new Vector(poolsize <= hardlimit ? poolsize
0264:                        : hardlimit);
0265:                reaper = new ConnectionReaper(this );
0266:                reaper.start();
0267:
0268:                if (DebugFile.trace)
0269:                    callers = new HashMap(1023);
0270:
0271:                errorlog = new LinkedList();
0272:            }
0273:
0274:            /**
0275:             * <p>Constructor</p>
0276:             * This method sets a default login timeout of 20 seconds
0277:             * @param bind DBBind owner of the connection pool (may be <b>null</b>)
0278:             * @param url JDBC URL string
0279:             * @param user Database user
0280:             * @param password Password for user
0281:             * @param maxpoolsize Maximum pool size
0282:             * @param maxconnections Maximum opened connections
0283:             * @param logintimeout Maximum time, in seconds, to wait for connection
0284:             * @since v2.2
0285:             */
0286:
0287:            public JDCConnectionPool(Object bind, String url, String user,
0288:                    String password, int maxpoolsize, int maxconnections,
0289:                    int logintimeout) {
0290:                this (bind, url, user, password, maxpoolsize, maxconnections,
0291:                        logintimeout, 60000l);
0292:            }
0293:
0294:            // ---------------------------------------------------------
0295:
0296:            /**
0297:             * <p>Constructor</p>
0298:             * This method sets a default login timeout of 20 seconds
0299:             * @param bind DBBind owner of the connection pool (may be <b>null</b>)
0300:             * @param url JDBC URL string
0301:             * @param user Database user
0302:             * @param password Password for user
0303:             * @param maxpoolsize Maximum pool size (Default 32)
0304:             * @param maxconnections Maximum opened connections (Default 100)
0305:             */
0306:            public JDCConnectionPool(Object bind, String url, String user,
0307:                    String password, int maxpoolsize, int maxconnections) {
0308:                this (bind, url, user, password, maxpoolsize, maxconnections, 20);
0309:            }
0310:
0311:            // ---------------------------------------------------------
0312:
0313:            /**
0314:             * <p>Constructor</p>
0315:             * @param url JDBC URL string
0316:             * @param user Database user
0317:             * @param password Password for user
0318:             * @param maxpoolsize Maximum pool size (Default 32)
0319:             * @param maxconnections Maximum opened connections (Default 100)
0320:             * @param logintimeout Maximum time, in seconds, to wait for connection
0321:             * @since v2.2
0322:             */
0323:
0324:            public JDCConnectionPool(String url, String user, String password,
0325:                    int maxpoolsize, int maxconnections, int logintimeout) {
0326:
0327:                binding = null;
0328:
0329:                if (null == url)
0330:                    throw new IllegalArgumentException(
0331:                            "JDCConnectionPool : url cannot be null");
0332:
0333:                if (url.length() == 0)
0334:                    throw new IllegalArgumentException(
0335:                            "JDCConnectionPool : url value not set");
0336:
0337:                if (maxpoolsize < 1)
0338:                    throw new IllegalArgumentException(
0339:                            "maxpoolsize must be greater than or equal to 1");
0340:
0341:                if (maxconnections < 1)
0342:                    throw new IllegalArgumentException(
0343:                            "maxpoolsize must be greater than or equal to 1");
0344:
0345:                if (maxpoolsize > maxconnections)
0346:                    throw new IllegalArgumentException(
0347:                            "maxpoolsize must be less than or equal to maxconnections");
0348:
0349:                this .url = url;
0350:                this .user = user;
0351:                this .password = password;
0352:                this .openconns = 0;
0353:                this .poolsize = maxpoolsize;
0354:                this .hardlimit = maxconnections;
0355:
0356:                DriverManager.setLoginTimeout(logintimeout);
0357:
0358:                connections = new Vector(poolsize);
0359:                reaper = new ConnectionReaper(this );
0360:                reaper.start();
0361:
0362:                if (DebugFile.trace)
0363:                    callers = new HashMap(1023);
0364:
0365:                errorlog = new LinkedList();
0366:            }
0367:
0368:            // ---------------------------------------------------------
0369:
0370:            /**
0371:             * <p>Constructor</p>
0372:             * This method sets a default login timeout of 20 seconds
0373:             * @param url JDBC URL string
0374:             * @param user Database user
0375:             * @param password Password for user
0376:             * @param maxpoolsize Maximum pool size (Default 32)
0377:             * @param maxconnections Maximum opened connections (Default 100)
0378:             */
0379:
0380:            // ---------------------------------------------------------
0381:            public JDCConnectionPool(String url, String user, String password,
0382:                    int maxpoolsize, int maxconnections) {
0383:                this (url, user, password, maxpoolsize, maxconnections, 20);
0384:            }
0385:
0386:            // ---------------------------------------------------------
0387:
0388:            private synchronized void modifyMap(String sCaller, int iAction)
0389:                    throws NullPointerException {
0390:
0391:                if (null == callers)
0392:                    callers = new HashMap(1023);
0393:
0394:                if (callers.containsKey(sCaller)) {
0395:                    Integer iRefCount = new Integer(((Integer) callers
0396:                            .get(sCaller)).intValue()
0397:                            + iAction);
0398:                    callers.remove(sCaller);
0399:                    callers.put(sCaller, iRefCount);
0400:                    DebugFile.writeln("  " + sCaller + " reference count is "
0401:                            + iRefCount.toString());
0402:                } else {
0403:                    if (1 == iAction) {
0404:                        callers.put(sCaller, new Integer(1));
0405:                        DebugFile.writeln("  " + sCaller
0406:                                + " reference count is 1");
0407:                    } else {
0408:                        DebugFile
0409:                                .writeln("  ERROR: JDCConnectionPool get/close connection mismatch for "
0410:                                        + sCaller);
0411:                    }
0412:                }
0413:            } // modifyMap
0414:
0415:            // ---------------------------------------------------------
0416:
0417:            /**
0418:             * Close all connections and stop connection reaper
0419:             */
0420:            public void close() {
0421:                if (DebugFile.trace) {
0422:                    DebugFile.writeln("Begin ConnectionPool.close()");
0423:                    DebugFile.incIdent();
0424:                }
0425:
0426:                reaper.halt();
0427:
0428:                closeConnections();
0429:
0430:                if (DebugFile.trace) {
0431:                    DebugFile.decIdent();
0432:                    DebugFile.writeln("End ConnectionPool.close()");
0433:                }
0434:            } // close
0435:
0436:            // ---------------------------------------------------------
0437:
0438:            /**
0439:             * <p>Get prefered open connections limit</p>
0440:             * <p>Additional connections beyond PoolSize may be opened but they
0441:             * will closed inmediately after use and not pooled.<br>The default value is 32.</p>
0442:             * @return open connections soft limit
0443:             */
0444:            public int getPoolSize() {
0445:                return poolsize;
0446:            }
0447:
0448:            // ---------------------------------------------------------
0449:
0450:            /**
0451:             * <p>Set prefered open connections limit</p>
0452:             * <p>Additional connections beyond PoolSize may be opened but they
0453:             * will closed inmediately after use and not pooled.<br>The default value is 32.<br>
0454:             * Connections not being used can only be in the pool for a maximum of five minutes.<br>
0455:             * After a connection is not used for over 5 minutes it will be closed so the actual
0456:             * pool size will eventually go down to zero after a period of inactivity.</p>
0457:             * @param iPoolSize Maximum pooled connections
0458:             */
0459:
0460:            public void setPoolSize(int iPoolSize) {
0461:
0462:                if (iPoolSize > hardlimit)
0463:                    throw new IllegalArgumentException(
0464:                            "prefered pool size must be less than or equal to max pool size ");
0465:
0466:                reapConnections();
0467:                poolsize = iPoolSize;
0468:            }
0469:
0470:            // ---------------------------------------------------------
0471:
0472:            /**
0473:             * <p>Set maximum concurrent open connections limit</p>
0474:             * The default value is 100.<br>
0475:             * If iMaxConnections is set to zero then the connection pool is effectively
0476:             * turned off and no pooling occurs.
0477:             * @param iMaxConnections Absolute maximum for opened connections
0478:             */
0479:            public void setMaxPoolSize(int iMaxConnections) {
0480:
0481:                if (iMaxConnections == 0) {
0482:                    reapConnections();
0483:                    poolsize = hardlimit = 0;
0484:                } else {
0485:                    if (iMaxConnections < poolsize)
0486:                        throw new IllegalArgumentException(
0487:                                "max pool size must be greater than or equal to prefered pool size ");
0488:
0489:                    reapConnections();
0490:                    hardlimit = iMaxConnections;
0491:                }
0492:            }
0493:
0494:            // ---------------------------------------------------------
0495:
0496:            /**
0497:             * <p>Absolute maximum allowed for concurrent opened connections.</p>
0498:             * The default value is 100.
0499:             */
0500:            public int getMaxPoolSize() {
0501:                return hardlimit;
0502:            }
0503:
0504:            /**
0505:             * <p>Get staled connection threshold</p>
0506:             * The default value is 600000ms (10 mins.)<br>
0507:             * This implies that all database operations done using connections
0508:             * obtained from the pool must be completed before 10 minutes or else
0509:             * they can be closed by the connection reaper before their normal finish.
0510:             * @return The maximum amount of time in miliseconds that a JDCConnection
0511:             * can be opened and not used before considering it staled.
0512:             */
0513:            public long getTimeout() {
0514:                return timeout;
0515:            }
0516:
0517:            // ---------------------------------------------------------
0518:
0519:            /**
0520:             * <p>Set staled connection threshold</p>
0521:             * @param miliseconds The maximum amount of time in miliseconds that a JDCConnection
0522:             * can be opened and not used before considering it staled.<BR>
0523:             * Default value is 600000ms (10 mins.) Minimum value is 1000.
0524:             * @throws IllegalArgumentException If miliseconds<1000
0525:             */
0526:
0527:            public void setTimeout(long miliseconds)
0528:                    throws IllegalArgumentException {
0529:
0530:                if (miliseconds < 1000l)
0531:                    throw new IllegalArgumentException(
0532:                            "Connection timeout must be at least 1000 miliseconds");
0533:
0534:                timeout = miliseconds;
0535:            }
0536:
0537:            /**
0538:             * Delay betwwen connection reaper executions
0539:             * @return long Number of miliseconds
0540:             * @since 3.0
0541:             */
0542:            public long getReaperDaemonDelay() {
0543:                return reaper.getDelay();
0544:            }
0545:
0546:            /**
0547:             * Set delay betwwen connection reaper executions (default value is 5 mins)
0548:             * @param lDelayMs long Miliseconds
0549:             * @throws IllegalArgumentException if lDelayMs is less than 1000
0550:             * @since 3.0
0551:             */
0552:            public void setReaperDaemonDelay(long lDelayMs)
0553:                    throws IllegalArgumentException {
0554:                reaper.setDelay(lDelayMs);
0555:            }
0556:
0557:            // ---------------------------------------------------------
0558:
0559:            /**
0560:             * Close and remove one connection from the pool
0561:             * @param conn Connection to close
0562:             */
0563:
0564:            private synchronized void removeConnection(JDCConnection conn) {
0565:                boolean bClosed;
0566:                String sCaller = "";
0567:
0568:                try {
0569:                    if (DebugFile.trace)
0570:                        logConnection(conn, "removeConnection", "RDBC", null);
0571:
0572:                    sCaller = conn.getName();
0573:                    if (!conn.isClosed())
0574:                        conn.getConnection().close();
0575:                    conn.expireLease();
0576:                    if (DebugFile.trace && (null != sCaller))
0577:                        modifyMap(sCaller, -1);
0578:                    bClosed = true;
0579:                } catch (SQLException e) {
0580:                    bClosed = false;
0581:
0582:                    if (errorlog.size() > 100)
0583:                        errorlog.removeFirst();
0584:                    errorlog.addLast(new Date().toString() + " " + sCaller
0585:                            + " Connection.close() " + e.getMessage());
0586:
0587:                    if (DebugFile.trace)
0588:                        DebugFile
0589:                                .writeln("SQLException at JDCConnectionPool.removeConnection() : "
0590:                                        + e.getMessage());
0591:                }
0592:
0593:                if (bClosed) {
0594:                    if (DebugFile.trace)
0595:                        DebugFile.writeln("connections.removeElement("
0596:                                + String.valueOf(openconns) + ")");
0597:                    connections.removeElement(conn);
0598:                    openconns--;
0599:                }
0600:            } // removeConnection()
0601:
0602:            // ---------------------------------------------------------
0603:
0604:            /**
0605:             * Called from the connection reaper daemon thread every n-minutes for maintaining the pool clean
0606:             */
0607:
0608:            synchronized void reapConnections() {
0609:
0610:                if (DebugFile.trace) {
0611:                    DebugFile
0612:                            .writeln("Begin JDCConnectionPool.reapConnections()");
0613:                    DebugFile.incIdent();
0614:                }
0615:
0616:                long stale = System.currentTimeMillis() - timeout;
0617:                Enumeration connlist = connections.elements();
0618:                JDCConnection conn;
0619:
0620:                while ((connlist != null) && (connlist.hasMoreElements())) {
0621:                    conn = (JDCConnection) connlist.nextElement();
0622:
0623:                    // Remove each connection that is not in use or
0624:                    // is stalled for more than maximun usage timeout (default 10 mins)
0625:                    if (!conn.inUse())
0626:                        removeConnection(conn);
0627:                    else if (stale > conn.getLastUse()) {
0628:                        if (DebugFile.trace)
0629:                            DebugFile.writeln("Connection " + conn.getName()
0630:                                    + " was staled since "
0631:                                    + new Date(conn.getLastUse()).toString());
0632:                        if (errorlog.size() > 100)
0633:                            errorlog.removeFirst();
0634:                        errorlog.addLast(new Date().toString() + " Connection "
0635:                                + conn.getName() + " was staled since "
0636:                                + new Date(conn.getLastUse()).toString());
0637:                        removeConnection(conn);
0638:                    }
0639:                } // wend
0640:
0641:                if (DebugFile.trace) {
0642:                    DebugFile.decIdent();
0643:                    DebugFile
0644:                            .writeln("End JDCConnectionPool.reapConnections() : "
0645:                                    + new Date().toString());
0646:                }
0647:            } // reapConnections()
0648:
0649:            // ---------------------------------------------------------
0650:
0651:            /**
0652:             * Close all connections from the pool regardless of their current state
0653:             */
0654:
0655:            public void closeConnections() {
0656:
0657:                Enumeration connlist;
0658:
0659:                if (DebugFile.trace) {
0660:                    DebugFile
0661:                            .writeln("Begin JDCConnectionPool.closeConnections()");
0662:                    DebugFile.incIdent();
0663:                }
0664:
0665:                connlist = connections.elements();
0666:
0667:                if (connlist != null) {
0668:                    while (connlist.hasMoreElements()) {
0669:                        removeConnection((JDCConnection) connlist.nextElement());
0670:                    } // wend
0671:                } // fi ()
0672:
0673:                if (DebugFile.trace)
0674:                    callers.clear();
0675:
0676:                connections.clear();
0677:
0678:                if (DebugFile.trace) {
0679:                    DebugFile.decIdent();
0680:                    DebugFile
0681:                            .writeln("End JDCConnectionPool.closeConnections() : "
0682:                                    + String.valueOf(openconns));
0683:                }
0684:
0685:                openconns = 0;
0686:            } // closeConnections()
0687:
0688:            // ---------------------------------------------------------
0689:
0690:            /**
0691:             * Close connections from the pool not used for a longer time
0692:             * @return Count of staled connections closed
0693:             */
0694:
0695:            public int closeStaledConnections() {
0696:
0697:                JDCConnection conn;
0698:                Enumeration connlist;
0699:
0700:                if (DebugFile.trace) {
0701:                    DebugFile
0702:                            .writeln("Begin JDCConnectionPool.closeStaledConnections()");
0703:                    DebugFile.incIdent();
0704:                }
0705:
0706:                int staled = 0;
0707:                final long stale = System.currentTimeMillis() - timeout;
0708:
0709:                connlist = connections.elements();
0710:
0711:                if (connlist != null) {
0712:                    while (connlist.hasMoreElements()) {
0713:                        conn = (JDCConnection) connlist.nextElement();
0714:                        if (stale > conn.getLastUse()) {
0715:                            staled++;
0716:                            removeConnection(conn);
0717:                        }
0718:                    } // wend
0719:                } // fi ()
0720:
0721:                if (DebugFile.trace) {
0722:                    DebugFile.decIdent();
0723:                    DebugFile
0724:                            .writeln("End JDCConnectionPool.closeStaledConnections() : "
0725:                                    + String.valueOf(staled));
0726:                }
0727:
0728:                return staled;
0729:            } // closeStaledConnections()
0730:
0731:            // ---------------------------------------------------------
0732:
0733:            private static void logConnection(JDCConnection conn, String sName,
0734:                    String cOpCode, String sParams) {
0735:
0736:                PreparedStatement oStmt = null;
0737:                JDCConnection oLogConn = null;
0738:
0739:                if (DebugFile.trace) {
0740:                    com.knowgate.dataobjs.DBAudit.log(JDCConnection.IdClass,
0741:                            cOpCode, "", sName, "", 0, "", sParams, "");
0742:                }
0743:
0744:            } // logConnection
0745:
0746:            // ---------------------------------------------------------
0747:
0748:            /**
0749:             * Get an array with references to all pooled connections
0750:             */
0751:            public synchronized JDCConnection[] getAllConnections() {
0752:                int iConnections = connections.size();
0753:                JDCConnection[] aConnections = new JDCConnection[iConnections];
0754:
0755:                for (int c = 0; c < iConnections; c++)
0756:                    aConnections[c] = (JDCConnection) connections.get(c);
0757:
0758:                return aConnections;
0759:            } // getAllConnections
0760:
0761:            // ---------------------------------------------------------
0762:
0763:            /**
0764:             * Get the DBbind object owner of this conenction pool
0765:             * @return DBBind instance or <b>null</b> if this connection pool has no owner
0766:             */
0767:            public Object getDatabaseBinding() {
0768:                return binding;
0769:            }
0770:
0771:            // ---------------------------------------------------------
0772:
0773:            /**
0774:             * Get a connection from the pool
0775:             * @param sCaller This is just an information parameter used for open/closed
0776:             * mismatch tracking and other benchmarking and statistical purposes.
0777:             * @return Opened JDCConnection
0778:             * @throws SQLException If getMaxPoolSize() opened connections is reached an
0779:             * SQLException with SQLState="08004" will be raised upon calling getConnection().<br>
0780:             * <b>Microsoft SQL Server</b>: Connection reuse requires that SelectMethod=cursor was
0781:             * specified at connection string.
0782:             */
0783:
0784:            public synchronized JDCConnection getConnection(String sCaller)
0785:                    throws SQLException {
0786:
0787:                int i, s;
0788:                JDCConnection j;
0789:                Connection c;
0790:
0791:                if (DebugFile.trace) {
0792:                    DebugFile.writeln("Begin JDCConnectionPool.getConnection("
0793:                            + (sCaller != null ? sCaller : "") + ")");
0794:                    DebugFile.incIdent();
0795:                }
0796:
0797:                if (hardlimit == 0) {
0798:                    // If hardlimit==0 Then connection pool is turned off so return a connection
0799:                    // directly from the DriverManager
0800:
0801:                    c = DriverManager.getConnection(url, user, password);
0802:                    j = new JDCConnection(c, null);
0803:                } else {
0804:
0805:                    j = null;
0806:
0807:                    s = connections.size();
0808:                    for (i = 0; i < s; i++) {
0809:                        j = (JDCConnection) connections.elementAt(i);
0810:                        if (j.lease(sCaller)) {
0811:                            if (DebugFile.trace) {
0812:                                DebugFile
0813:                                        .writeln("  JDCConnectionPool hit for ("
0814:                                                + url
0815:                                                + ", ...) on pooled connection #"
0816:                                                + String.valueOf(i));
0817:                                if (sCaller != null)
0818:                                    logConnection(j, sCaller, "ODBC", "hit");
0819:                            }
0820:                            break;
0821:                        } else
0822:                            j = null;
0823:                    } // endfor
0824:
0825:                    if (null == j) {
0826:                        if (openconns == hardlimit) {
0827:                            if (DebugFile.trace)
0828:                                DebugFile.decIdent();
0829:                            throw new SQLException("Maximum number of "
0830:                                    + String.valueOf(hardlimit)
0831:                                    + " concurrent connections exceeded",
0832:                                    "08004");
0833:                        }
0834:
0835:                        if (DebugFile.trace)
0836:                            DebugFile.writeln("  DriverManager.getConnection("
0837:                                    + url + ", ...)");
0838:
0839:                        c = DriverManager.getConnection(url, user, password);
0840:
0841:                        if (null != c) {
0842:                            j = new JDCConnection(c, this );
0843:                            j.lease(sCaller);
0844:
0845:                            if (DebugFile.trace) {
0846:                                DebugFile
0847:                                        .writeln("  JDCConnectionPool miss for ("
0848:                                                + url + ", ...)");
0849:                                if (sCaller != null)
0850:                                    logConnection(j, sCaller, "ODBC", "miss");
0851:                            }
0852:
0853:                            connections.addElement(j);
0854:                            c = null;
0855:                        } else {
0856:                            if (DebugFile.trace)
0857:                                DebugFile
0858:                                        .writeln("JDCConnectionPool.getConnection() DriverManager.getConnection() returned null value");
0859:                            j = null;
0860:                        }
0861:
0862:                        if (null != j)
0863:                            openconns++;
0864:                    } // endif (null==j)
0865:
0866:                    if (DebugFile.trace) {
0867:                        if (sCaller != null)
0868:                            modifyMap(sCaller, 1);
0869:                    } // DebugFile()
0870:                } // fi (hardlimit==0)
0871:
0872:                if (DebugFile.trace) {
0873:                    DebugFile.decIdent();
0874:                    DebugFile.writeln("End JDCConnectionPool.getConnection()");
0875:                } // DebugFile()
0876:
0877:                return j;
0878:            } // getConnection()
0879:
0880:            // ---------------------------------------------------------
0881:
0882:            /**
0883:             * Get conenction for a server process identifier
0884:             * @param sPId String Operating system process identifier at server side
0885:             * @return JDCConnection or <b>null</b> if no connection for such pid was found
0886:             * @throws SQLException
0887:             * @since 2.2
0888:             */
0889:            public JDCConnection getConnectionForPId(String sPId)
0890:                    throws SQLException {
0891:                String pid;
0892:                JDCConnection conn;
0893:                Enumeration connlist = connections.elements();
0894:                if (connlist != null) {
0895:                    while (connlist.hasMoreElements()) {
0896:                        conn = (JDCConnection) connlist.nextElement();
0897:                        try {
0898:                            pid = conn.pid();
0899:                        } catch (Exception ignore) {
0900:                            pid = null;
0901:                        }
0902:                        if (sPId.equals(pid))
0903:                            return conn;
0904:                    } // wend
0905:                } // fi ()
0906:                return null;
0907:            } // getConnectionForPId
0908:
0909:            // ---------------------------------------------------------
0910:
0911:            /**
0912:             * Return a connection to the pool
0913:             * @param conn JDCConnection returned to the pool
0914:             */
0915:
0916:            public synchronized void returnConnection(JDCConnection conn) {
0917:                if (DebugFile.trace)
0918:                    DebugFile
0919:                            .writeln("JDCConnectionPool.returnConnection([JDCConnection])");
0920:                conn.expireLease();
0921:            } // returnConnection()
0922:
0923:            // ---------------------------------------------------------
0924:
0925:            /**
0926:             * Return a connection to the pool
0927:             * @param conn JDCConnection returned to the pool
0928:             * @param sCaller Must be the same String passed as parameter at getConnection()
0929:             */
0930:
0931:            public synchronized void returnConnection(JDCConnection conn,
0932:                    String sCaller) {
0933:
0934:                if (DebugFile.trace) {
0935:                    DebugFile
0936:                            .writeln("JDCConnectionPool.returnConnection([JDCConnection], "
0937:                                    + sCaller + ")");
0938:                    if (sCaller != null)
0939:                        logConnection(conn, sCaller, "CDBC", null);
0940:                }
0941:
0942:                if (DebugFile.trace)
0943:                    DebugFile.writeln("JDCConnection.expireLease()");
0944:
0945:                conn.expireLease();
0946:
0947:                if (DebugFile.trace && (null != sCaller))
0948:                    modifyMap(sCaller, -1);
0949:            }
0950:
0951:            // ---------------------------------------------------------
0952:
0953:            /**
0954:             * @return Actual connection pool size
0955:             */
0956:
0957:            public synchronized int size() {
0958:                return openconns;
0959:            }
0960:
0961:            /**
0962:             * Get information of current activity at database to which this pool is connected
0963:             * @return JDCActivityInfo
0964:             * @throws SQLException
0965:             * @since 3.0
0966:             */
0967:            public JDCActivityInfo getActivityInfo() throws SQLException {
0968:                JDCActivityInfo oInfo;
0969:                try {
0970:                    oInfo = new JDCActivityInfo(this );
0971:                } catch (Exception xcpt) {
0972:                    throw new SQLException(xcpt.getMessage());
0973:                }
0974:                return oInfo;
0975:            }
0976:
0977:            // ---------------------------------------------------------
0978:
0979:            /**
0980:             * Human readable usage statistics
0981:             * @return Connection pool usage statistics string
0982:             * @throws ConcurrentModificationException If pool is modified while iterating
0983:             * throught connection collection
0984:             */
0985:            public String dumpStatistics()
0986:                    throws ConcurrentModificationException {
0987:                String sDump;
0988:                String sPId;
0989:                Object sKey;
0990:                Object iVal;
0991:                int iConnOrdinal, iStaled;
0992:                long stale = System.currentTimeMillis() - timeout;
0993:
0994:                if (DebugFile.trace) {
0995:                    DebugFile
0996:                            .writeln("Begin JDCConnectionPool.dumpStatistics()");
0997:                    DebugFile.incIdent();
0998:                }
0999:
1000:                Enumeration connlist = connections.elements();
1001:                JDCConnection conn;
1002:
1003:                sDump = "Maximum Pool Size=" + String.valueOf(poolsize) + "\n";
1004:                sDump += "Maximum Connections=" + String.valueOf(hardlimit)
1005:                        + "\n";
1006:                sDump += "Connection Timeout=" + String.valueOf(timeout)
1007:                        + " ms\n";
1008:                sDump += "Reaper Daemon Delay="
1009:                        + String.valueOf(getReaperDaemonDelay()) + " ms\n";
1010:                sDump += "\n";
1011:
1012:                iStaled = iConnOrdinal = 0;
1013:
1014:                if (connlist != null) {
1015:                    while (connlist.hasMoreElements()) {
1016:                        conn = (JDCConnection) connlist.nextElement();
1017:
1018:                        if (stale > conn.getLastUse())
1019:                            iStaled++;
1020:
1021:                        try {
1022:                            sPId = conn.pid();
1023:                        } catch (Exception ignore) {
1024:                            sPId = null;
1025:                        }
1026:
1027:                        sDump += "#"
1028:                                + String.valueOf(++iConnOrdinal)
1029:                                + (conn.inUse() ? " in use, " : " vacant, ")
1030:                                + (stale > conn.getLastUse() ? " staled,"
1031:                                        : " ready,")
1032:                                + (conn.validate() ? "validate=yes"
1033:                                        : " validate=no") + ", last use="
1034:                                + new Date(conn.getLastUse()).toString()
1035:                                + ", caller=" + conn.getName()
1036:                                + (sPId == null ? "" : " pid=" + sPId) + "\n";
1037:                    }
1038:                } // fi ()
1039:
1040:                sDump += "\n";
1041:
1042:                if (DebugFile.trace) {
1043:                    Iterator oCallersIterator = callers.keySet().iterator();
1044:
1045:                    while (oCallersIterator.hasNext()) {
1046:                        sKey = oCallersIterator.next();
1047:                        iVal = callers.get(sKey);
1048:                        sDump += sKey + " , " + iVal.toString()
1049:                                + " named open connections\n";
1050:                    }
1051:                    sDump += "\n\n";
1052:                } // fi (DebugFile.trace)
1053:
1054:                sDump += String.valueOf(iStaled) + " staled connections\n";
1055:
1056:                sDump += "Actual pool size " + String.valueOf(size()) + "\n\n";
1057:
1058:                try {
1059:                    JDCProcessInfo[] oPinfo = getActivityInfo().processesInfo();
1060:                    if (oPinfo != null) {
1061:                        sDump += "Activity information:\n";
1062:                        for (int p = 0; p < oPinfo.length; p++) {
1063:                            sDump += "user " + oPinfo[p].getUserName()
1064:                                    + " running process "
1065:                                    + oPinfo[p].getProcessId();
1066:                            conn = getConnectionForPId(oPinfo[p].getProcessId());
1067:                            if (conn != null) {
1068:                                sDump += " on connection " + conn.getName();
1069:                            }
1070:                            if (oPinfo[p].getQueryText().length() > 0) {
1071:                                sDump += " for query "
1072:                                        + oPinfo[p].getQueryText();
1073:                            }
1074:                            if (oPinfo[p].getQueryStart() != null) {
1075:                                sDump += " since "
1076:                                        + oPinfo[p].getQueryStart().toString();
1077:                            }
1078:                            sDump += "\n";
1079:                        } // next
1080:                    }
1081:                } catch (Exception xcpt) {
1082:                    sDump += xcpt.getClass().getName()
1083:                            + " trying to get activity information "
1084:                            + xcpt.getMessage() + "\n";
1085:                }
1086:
1087:                sDump += "\n";
1088:
1089:                if (errorlog.size() > 0) {
1090:                    sDump += "Fatal error log:\n";
1091:                    ListIterator oErrIterator = errorlog.listIterator();
1092:                    while (oErrIterator.hasNext())
1093:                        sDump += oErrIterator.next() + "\n";
1094:                } // fi
1095:
1096:                if (DebugFile.trace) {
1097:                    DebugFile.decIdent();
1098:                    DebugFile.writeln("End JDCConnectionPool.dumpStatistics()");
1099:                }
1100:
1101:                return sDump;
1102:            } // dumpStatistics
1103:
1104:        } // JDCConnectionPool
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.