Source Code Cross Referenced for DBConnectionManager.java in  » Forum » mvnforum-1.1 » net » myvietnam » mvncore » db » 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 » Forum » mvnforum 1.1 » net.myvietnam.mvncore.db 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $Header: /cvsroot/mvnforum/myvietnam/src/net/myvietnam/mvncore/db/DBConnectionManager.java,v 1.22 2007/11/22 04:40:29 minhnn Exp $
003:         * $Author: minhnn $
004:         * $Revision: 1.22 $
005:         * $Date: 2007/11/22 04:40:29 $
006:         *
007:         * ====================================================================
008:         *
009:         * Copyright (C) 2002-2007 by MyVietnam.net
010:         *
011:         * All copyright notices regarding MyVietnam and MyVietnam CoreLib
012:         * MUST remain intact in the scripts and source code.
013:         *
014:         * This library is free software; you can redistribute it and/or
015:         * modify it under the terms of the GNU Lesser General Public
016:         * License as published by the Free Software Foundation; either
017:         * version 2.1 of the License, or (at your option) any later version.
018:         *
019:         * This library is distributed in the hope that it will be useful,
020:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
021:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
022:         * Lesser General Public License for more details.
023:         *
024:         * You should have received a copy of the GNU Lesser General Public
025:         * License along with this library; if not, write to the Free Software
026:         * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
027:         *
028:         * Correspondence and Marketing Questions can be sent to:
029:         * info at MyVietnam net
030:         *
031:         * @author: Minh Nguyen  
032:         * @author: Mai  Nguyen  
033:         */
034:        package net.myvietnam.mvncore.db;
035:
036:        import java.sql.*;
037:        import java.util.*;
038:
039:        import net.myvietnam.mvncore.MVNCoreConfig;
040:        import org.apache.commons.logging.Log;
041:        import org.apache.commons.logging.LogFactory;
042:
043:        /**
044:         * This class is a Singleton that provides access to the
045:         * connection pool. A client gets access to the single
046:         * instance through the static getInstance() method
047:         * and can then check-out and check-in connections from a pool.
048:         * When the client shuts down it should call the release() method
049:         * to close all opened connections and do other clean up.
050:         */
051:        class DBConnectionManager {
052:
053:            private static Log log = LogFactory
054:                    .getLog(DBConnectionManager.class);
055:
056:            private static final int TIME_BETWEEN_RETRIES = 500; // O.5 second
057:
058:            // static variable
059:            static private DBConnectionManager instance = null; // The single instance
060:
061:            // instance variable
062:            private DBConnectionPool pool = null;// please be careful if u want to make this variable static
063:
064:            private static Map dbManagers = new HashMap();
065:            private static final int MANAGER_MAX = 5;
066:
067:            /**
068:             * A private constructor since this is a Singleton
069:             * Note: This constructor is lightweight since DBConnectionPool is lightweight,
070:             *       so no connection is created until the first time getConnection() is called
071:             */
072:            private DBConnectionManager() {
073:                String driverClassName = MVNCoreConfig.getDriverClassName();
074:                try {
075:                    Class.forName(driverClassName).newInstance();
076:                } catch (Exception e) {
077:                    log.fatal("DBConnectionManager: Unable to load driver = "
078:                            + driverClassName, e);
079:                }
080:
081:                String url = MVNCoreConfig.getDatabaseURL();
082:                String user = MVNCoreConfig.getDatabaseUser();
083:                String password = MVNCoreConfig.getDatabasePassword();
084:                int maxConnection = MVNCoreConfig.getMaxConnection();
085:
086:                //always new the pool because pool is an instance variable
087:                pool = new DBConnectionPool(url, user, password, maxConnection);
088:            }
089:
090:            private DBConnectionManager(DBOptions dbOptions) {
091:                String driverClassName = dbOptions.getDriverClass();
092:                try {
093:                    Class.forName(driverClassName).newInstance();
094:                } catch (Exception e) {
095:                    log.fatal("DBConnectionManager: Unable to load driver = "
096:                            + driverClassName, e);
097:                }
098:
099:                String url = dbOptions.getDbUrl();
100:                String user = dbOptions.getUsername();
101:                String password = dbOptions.getPassword();
102:                int maxConnection = dbOptions.getConMax();
103:
104:                //always new the pool because pool is an instance variable
105:                pool = new DBConnectionPool(url, user, password, maxConnection);
106:            }
107:
108:            /**
109:             * Returns the single instance, creating one if it's the
110:             * first time this method is called.
111:             *
112:             * @return DBConnectionManager The single instance.
113:             */
114:            /*
115:            public static synchronized DBConnectionManager getInstance() {
116:                if (instance == null) {
117:                    DBOptions option = new DBOptions();
118:                    instance = new DBConnectionManager(option);
119:                }
120:                return instance;
121:            }*/
122:
123:            /**
124:             * Returns the single instance, creating one if it's the
125:             * first time this method is called.
126:             *
127:             * @return DBConnectionManager The single instance.
128:             */
129:            /*
130:            private static synchronized DBConnectionManager getInstance(DBOptions option) {
131:                if (instance == null) {
132:                    if (option == null) {
133:                        option = new DBOptions();
134:                    }
135:                    instance = new DBConnectionManager(option);
136:                }
137:                return instance;
138:            }*/
139:
140:            /**
141:             * DBUtil use this method
142:             */
143:            public static synchronized DBConnectionManager getInstance(
144:                    boolean useConfig) {
145:                if (instance == null) {
146:                    instance = new DBConnectionManager();
147:                }
148:                return instance;
149:            }
150:
151:            /**
152:             * DBUtil2 use this method
153:             */
154:            public static synchronized DBConnectionManager getDBConnectionManager(
155:                    DBOptions dbOptions) {
156:
157:                if (dbOptions == null) {
158:                    throw new IllegalArgumentException(
159:                            "Cannot get DBConnectionManager. Missing DBOptions.");
160:                }
161:
162:                if ((dbOptions.getDbManagerName() == null)
163:                        || (dbOptions.getDbManagerName().length() == 0)) {
164:                    throw new IllegalArgumentException(
165:                            "Cannot get DBConnectionManager. Missing [Database Connection Manager Name].");
166:                }
167:
168:                DBConnectionManager dbManager = (DBConnectionManager) dbManagers
169:                        .get(dbOptions.getDbManagerName());
170:                if (dbManager == null) {
171:                    dbManager = createDbConnectionManager(dbOptions);
172:                }
173:                return dbManager;
174:            }
175:
176:            private static DBConnectionManager createDbConnectionManager(
177:                    DBOptions dbOptions) {
178:
179:                if (dbManagers.size() >= MANAGER_MAX) {
180:                    throw new IllegalStateException("System only support max "
181:                            + MANAGER_MAX + " DBConnectionManager(s)");
182:                }
183:
184:                DBConnectionManager instance = new DBConnectionManager(
185:                        dbOptions);
186:                dbManagers.put(dbOptions.getDbManagerName(), instance);
187:
188:                return instance;
189:            }
190:
191:            /**
192:             * Returns a connection to the pool.
193:             *
194:             * @param con The Connection
195:             */
196:            void freeConnection(Connection con) {
197:                pool.freeConnection(con);
198:            }
199:
200:            /**
201:             * Returns an open connection. If no one is available, and the max
202:             * number of connections has not been reached, a new connection is
203:             * created.
204:             *
205:             * @return Connection The connection or null
206:             */
207:            Connection getConnection() {
208:                return getConnection(0);
209:            }
210:
211:            /**
212:             * Returns an open connection. If no one is available, and the max
213:             * number of connections has not been reached, a new connection is
214:             * created. If the max number has been reached, waits until one
215:             * is available or the specified time has elapsed.
216:             *
217:             * @param time The number of milliseconds to wait
218:             * @return Connection The connection or null
219:             */
220:            Connection getConnection(long time) {
221:                Connection connection = pool.getConnection(time);
222:                if (connection == null) {
223:                    return null;
224:                }
225:
226:                try {
227:                    // we always setAutoCommit(true) for backward compatible with mvnForum
228:                    connection.setAutoCommit(true);
229:                } catch (SQLException e) {
230:                    log.error("Cannot setAutoCommit", e);
231:                }
232:                ConnectionWrapper wrapper = new ConnectionWrapper(connection,
233:                        this );
234:                return wrapper;
235:            }
236:
237:            /**
238:             * Closes all open connections.
239:             * @return true if the pool is empty and balance
240:             *         false if the pool has returned some connection to outside
241:             */
242:            boolean release() {
243:                return pool.release();
244:            }
245:
246:            /**
247:             * This inner class represents a connection pool. It creates new
248:             * connections on demand, up to a max number if specified.
249:             * It also checks to make sure that the connection is still open
250:             * before it is returned to a client.
251:             */
252:            class DBConnectionPool {
253:                private int checkedOut = 0;//NOTE: this variable should be changed in synchronized method only
254:                private Vector freeConnections = new Vector();
255:
256:                private int maxConn = 0;
257:                private String password = null;
258:                private String URL = null;
259:                private String user = null;
260:
261:                /**
262:                 * Creates new connection pool.
263:                 * NOTE: new an instance of this class is lightweight since it does not create any connections
264:                 *
265:                 * @param URL The JDBC URL for the database
266:                 * @param user The database user, or null
267:                 * @param password The database user password, or null
268:                 * @param maxConn The maximal number of connections, or 0 for no limit
269:                 */
270:                public DBConnectionPool(String URL, String user,
271:                        String password, int maxConn) {
272:                    this .URL = URL;
273:                    this .user = user;
274:                    this .password = password;
275:                    this .maxConn = maxConn;
276:                }
277:
278:                /**
279:                 * Checks in a connection to the pool. Notify other Threads that
280:                 * may be waiting for a connection.
281:                 *
282:                 * @todo: Maybe we dont need notifyAll(); ???
283:                 *
284:                 * @param con The connection to check in
285:                 */
286:                synchronized void freeConnection(Connection con) {
287:                    // Put the connection at the end of the Vector
288:                    if (con != null) {//make sure that the connection is not null
289:                        if (checkedOut <= 0) {
290:                            // this means that connection is open too much
291:                            // There are 2 cases:
292:                            // 1. Not get from this connection pool (maybe get directly)
293:                            // 2. this connection is gotten and then the whole pool is released
294:                            // In these case, just close the connection
295:                            try {
296:                                log
297:                                        .debug("DBConnectionManager: about to close the orphan connection.");
298:                                con.close();
299:                            } catch (SQLException ex) {
300:                            }
301:                        } else {
302:                            // Return this connection to the pool
303:                            // note that we dont have to check if the connection is not connected
304:                            // this will be check in the getConnection method
305:                            freeConnections.addElement(con);
306:                            // FIXME: posible negative value
307:                            // NOTE: checkOut should never be negative here
308:                            checkedOut--; // NOTE: this number can be negative (in case connection does not come from the pool)
309:                            notifyAll(); // can I remove it ???
310:                        }
311:                    }
312:                }
313:
314:                /**
315:                 * Checks out a connection from the pool. If no free connection
316:                 * is available, a new connection is created unless the max
317:                 * number of connections has been reached. If a free connection
318:                 * has been closed by the database, it's removed from the pool
319:                 * and this method is called again recursively.
320:                 */
321:                synchronized Connection getConnection() {
322:                    Connection con = null;
323:
324:                    while ((freeConnections.size() > 0) && (con == null)) {
325:                        // Pick the first Connection in the Vector
326:                        // to get round-robin usage
327:                        con = (Connection) freeConnections.firstElement();
328:                        freeConnections.removeElementAt(0);
329:                        try {
330:                            if (con.isClosed()) {
331:                                log
332:                                        .info("Removed bad connection in DBConnectionPool.");
333:                                con = null; // to make the while loop to continue
334:                            }
335:                        } catch (SQLException e) {
336:                            con = null; // to make the while loop to continue
337:                        }
338:                    } // while
339:
340:                    if (con == null) {// cannot get any connection from the pool
341:                        if (maxConn == 0 || checkedOut < maxConn) {// maxConn = 0 means unlimited connections
342:                            con = newConnection();
343:                        }
344:                    }
345:                    if (con != null) {
346:                        checkedOut++;
347:                    }
348:                    return con;
349:                }
350:
351:                /**
352:                 * Checks out a connection from the pool. If no free connection
353:                 * is available, a new connection is created unless the max
354:                 * number of connections has been reached. If a free connection
355:                 * has been closed by the database, it's removed from the pool
356:                 * and this method is called again recursively.
357:                 * <P>
358:                 * If no connection is available and the max number has been
359:                 * reached, this method waits the specified time for one to be
360:                 * checked in.
361:                 *
362:                 * @param timeout The timeout value in milliseconds
363:                 */
364:                /**
365:                 * Note that this method is not synchronized since it relies on the getConnection(void) method
366:                 * I also believe that this method SHOULD NOT synchronized because I use #sleep() method
367:                 * @todo: check if we should synchronize this method and use wait instead of sleep ???
368:                 */
369:                Connection getConnection(long timeout) {
370:                    long startTime = System.currentTimeMillis();
371:                    Connection con;
372:                    while ((con = getConnection()) == null) {
373:                        long elapsedTime = System.currentTimeMillis()
374:                                - startTime;
375:                        if (elapsedTime >= timeout) {
376:                            // Timeout has expired
377:                            return null;
378:                        }
379:
380:                        long timeToWait = timeout - elapsedTime;
381:                        if (timeToWait > TIME_BETWEEN_RETRIES)
382:                            timeToWait = TIME_BETWEEN_RETRIES;// we dont want to wait for more than TIME_BETWEEN_RETRIES second each time
383:                        try {
384:                            Thread.sleep(timeToWait);
385:                        } catch (InterruptedException e) {
386:                        }
387:                    }
388:                    return con;
389:                }
390:
391:                /**
392:                 * Closes all available connections.
393:                 * @return true if the pool is empty and balance
394:                 *         false if the pool has returned some connection to outside
395:                 */
396:                synchronized boolean release() {
397:                    boolean retValue = true;
398:                    Enumeration allConnections = freeConnections.elements();
399:                    while (allConnections.hasMoreElements()) {
400:                        Connection con = (Connection) allConnections
401:                                .nextElement();
402:                        try {
403:                            con.close();
404:                        } catch (SQLException e) {
405:                            log
406:                                    .error("Cannot close connection in DBConnectionPool.");
407:                        }
408:                    }
409:                    freeConnections.removeAllElements();
410:                    if (checkedOut != 0) {
411:                        retValue = false;
412:                        log
413:                                .warn("DBConnectionManager: the built-in connection pool is not balanced.");
414:                    }
415:                    checkedOut = 0;
416:                    return retValue;
417:                }
418:
419:                /**
420:                 * Creates a new connection, using a userid and password
421:                 * if specified.
422:                 * @todo: check if this method need synchronized
423:                 */
424:                private Connection newConnection() {
425:                    Connection con = null;
426:                    try {
427:                        if (user == null) {
428:                            con = DriverManager.getConnection(URL);
429:                        } else {
430:                            con = DriverManager.getConnection(URL, user,
431:                                    password);
432:                        }
433:                        // Note that we dont need to call setAutoCommit here because we 
434:                        // will call it at DBConnectionManager.getConnection()
435:                        //con.setAutoCommit(true);//thread 804 by trulore
436:                    } catch (SQLException e) {
437:                        log.error(
438:                                "Cannot create a new connection in DBConnectionPool. URL = "
439:                                        + URL, e);
440:                        return null;
441:                    }
442:                    return con;
443:                }
444:            }
445:
446:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.