Source Code Cross Referenced for ConnectionPool.java in  » EJB-Server-resin-3.1.5 » resin » com » caucho » jca » 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 » EJB Server resin 3.1.5 » resin » com.caucho.jca 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
0003:         *
0004:         * This file is part of Resin(R) Open Source
0005:         *
0006:         * Each copy or derived work must preserve the copyright notice and this
0007:         * notice unmodified.
0008:         *
0009:         * Resin Open Source is free software; you can redistribute it and/or modify
0010:         * it under the terms of the GNU General Public License as published by
0011:         * the Free Software Foundation; either version 2 of the License, or
0012:         * (at your option) any later version.
0013:         *
0014:         * Resin Open Source is distributed in the hope that it will be useful,
0015:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
0017:         * of NON-INFRINGEMENT.  See the GNU General Public License for more
0018:         * details.
0019:         *
0020:         * You should have received a copy of the GNU General Public License
0021:         * along with Resin Open Source; if not, write to the
0022:         *
0023:         *   Free Software Foundation, Inc.
0024:         *   59 Temple Place, Suite 330
0025:         *   Boston, MA 02111-1307  USA
0026:         *
0027:         * @author Scott Ferguson
0028:         */
0029:
0030:        package com.caucho.jca;
0031:
0032:        import com.caucho.config.ConfigException;
0033:        import com.caucho.config.types.Period;
0034:        import com.caucho.lifecycle.Lifecycle;
0035:        import com.caucho.management.server.AbstractManagedObject;
0036:        import com.caucho.management.server.ConnectionPoolMXBean;
0037:        import com.caucho.sql.ManagedConnectionImpl;
0038:        import com.caucho.util.Alarm;
0039:        import com.caucho.util.AlarmListener;
0040:        import com.caucho.util.L10N;
0041:        import com.caucho.util.FifoSet;
0042:        import com.caucho.util.WeakAlarm;
0043:
0044:        import javax.resource.NotSupportedException;
0045:        import javax.resource.ResourceException;
0046:        import javax.resource.spi.ConnectionManager;
0047:        import javax.resource.spi.ConnectionRequestInfo;
0048:        import javax.resource.spi.ManagedConnection;
0049:        import javax.resource.spi.ManagedConnectionFactory;
0050:        import javax.resource.spi.ValidatingManagedConnectionFactory;
0051:        import javax.security.auth.Subject;
0052:        import javax.transaction.xa.XAResource;
0053:        import javax.transaction.xa.Xid;
0054:        import java.util.ArrayList;
0055:        import java.util.Set;
0056:        import java.util.Date;
0057:        import java.util.logging.Level;
0058:        import java.util.logging.Logger;
0059:
0060:        /**
0061:         * Implementation of the connection manager.
0062:         */
0063:        public class ConnectionPool extends AbstractManagedObject implements 
0064:                ConnectionManager, AlarmListener, ConnectionPoolMXBean {
0065:            private static final L10N L = new L10N(ConnectionPool.class);
0066:            private static final Logger log = Logger
0067:                    .getLogger(ConnectionPool.class.getName());
0068:
0069:            private static int _idGen;
0070:
0071:            private String _name;
0072:
0073:            private UserTransactionProxy _tm;
0074:
0075:            // the maximum number of connections
0076:            private int _maxConnections = 128;
0077:
0078:            // the maximum number of overflow connections
0079:            private int _maxOverflowConnections = 0;
0080:
0081:            // the maximum number of connections being created
0082:            private int _maxCreateConnections = 5;
0083:
0084:            // max idle size
0085:            private int _maxIdleCount = 1024;
0086:
0087:            // time before an idle connection is closed (30s default)
0088:            private long _maxIdleTime = 30000L;
0089:
0090:            // time before an active connection is closed (6h default)
0091:            private long _maxActiveTime = 6L * 3600L * 1000L;
0092:
0093:            // time a connection is allowed to be used (24h default)
0094:            private long _maxPoolTime = 24L * 3600L * 1000L;
0095:
0096:            // the time to wait for a connection (10m)
0097:            private long _connectionWaitTime = 600 * 1000L;
0098:
0099:            // the time to wait for a connection
0100:            private long _connectionWaitCount = _connectionWaitTime / 1000L;
0101:
0102:            // True if the connector supports local transactions.
0103:            private boolean _enableLocalTransaction = true;
0104:
0105:            // True if the connector supports XA transactions.
0106:            private boolean _enableXA = true;
0107:
0108:            // True if the local transaction optimization is allowed.
0109:            private boolean _isLocalTransactionOptimization = true;
0110:
0111:            // server/3087
0112:            private boolean _isShareable = true;
0113:
0114:            // If true, the save a stack trace when the collection is allocated
0115:            private boolean _saveAllocationStackTrace = false;
0116:
0117:            // If true, close dangling connections
0118:            private boolean _isCloseDanglingConnections = true;
0119:
0120:            private final ArrayList<PoolItem> _pool = new ArrayList<PoolItem>();
0121:
0122:            private IdlePoolSet _idlePool;
0123:
0124:            // temporary connection list for the alarm callback
0125:            private final ArrayList<PoolItem> _alarmConnections = new ArrayList<PoolItem>();
0126:
0127:            private Alarm _alarm;
0128:
0129:            // time of the last validation check
0130:            private long _lastValidCheckTime;
0131:            // time the idle set was last empty
0132:            private long _lastIdlePoolEmptyTime;
0133:
0134:            private int _idCount;
0135:
0136:            private int _createCount;
0137:
0138:            //
0139:            // statistics
0140:            //
0141:
0142:            private long _connectionCountTotal;
0143:            private long _connectionCreateCountTotal;
0144:            private long _connectionFailCountTotal;
0145:            private long _lastFailTime;
0146:
0147:            private final Lifecycle _lifecycle = new Lifecycle();
0148:
0149:            ConnectionPool() {
0150:            }
0151:
0152:            /**
0153:             * Sets the connection pool name.
0154:             */
0155:            public void setName(String name) {
0156:                _name = name;
0157:            }
0158:
0159:            /**
0160:             * Gets the connection pool name.
0161:             */
0162:            public String getName() {
0163:                return _name;
0164:            }
0165:
0166:            /**
0167:             * Sets the transaction manager.
0168:             */
0169:            public void setTransactionManager(UserTransactionProxy tm) {
0170:                _tm = tm;
0171:            }
0172:
0173:            /**
0174:             * Returns the transaction manager.
0175:             */
0176:            public UserTransactionProxy getTransactionManager() {
0177:                return _tm;
0178:            }
0179:
0180:            /**
0181:             * Returns true if shared connections are allowed.
0182:             */
0183:            public boolean isShareable() {
0184:                return _isShareable;
0185:            }
0186:
0187:            /**
0188:             * Returns true if shared connections are allowed.
0189:             */
0190:            public void setShareable(boolean isShareable) {
0191:                _isShareable = isShareable;
0192:            }
0193:
0194:            /**
0195:             * Returns true if the local transaction optimization is enabled
0196:             */
0197:            public boolean isLocalTransactionOptimization() {
0198:                return _isLocalTransactionOptimization;
0199:            }
0200:
0201:            /**
0202:             * Returns true if the local transaction optimization is enabled
0203:             */
0204:            public void setLocalTransactionOptimization(boolean enable) {
0205:                _isLocalTransactionOptimization = enable;
0206:            }
0207:
0208:            /**
0209:             * Returns true if the local transaction optimization is enabled
0210:             */
0211:            public boolean allowLocalTransactionOptimization() {
0212:                return _isLocalTransactionOptimization && _isShareable;
0213:            }
0214:
0215:            /**
0216:             * Returns true if a stack trace should be shared on allocation
0217:             */
0218:            public boolean getSaveAllocationStackTrace() {
0219:                return _saveAllocationStackTrace;
0220:            }
0221:
0222:            /**
0223:             * Returns true if a stack trace should be shared on allocation
0224:             */
0225:            public void setSaveAllocationStackTrace(boolean save) {
0226:                _saveAllocationStackTrace = save;
0227:            }
0228:
0229:            /**
0230:             * Returns true if dangling connections should be closed
0231:             */
0232:            public boolean isCloseDanglingConnections() {
0233:                return _isCloseDanglingConnections;
0234:            }
0235:
0236:            /**
0237:             * True if dangling connections should be closed.
0238:             */
0239:            public void setCloseDanglingConnections(boolean isClose) {
0240:                _isCloseDanglingConnections = isClose;
0241:            }
0242:
0243:            /**
0244:             * Set true for local transaction support.
0245:             */
0246:            public void setLocalTransaction(boolean localTransaction) {
0247:                _enableLocalTransaction = localTransaction;
0248:            }
0249:
0250:            /**
0251:             * Set true for local transaction support.
0252:             */
0253:            public boolean isLocalTransaction() {
0254:                return _enableLocalTransaction;
0255:            }
0256:
0257:            /**
0258:             * Set true for XA transaction support.
0259:             */
0260:            public void setXATransaction(boolean enable) {
0261:                _enableXA = enable;
0262:            }
0263:
0264:            /**
0265:             * Set true for XA transaction support.
0266:             */
0267:            public boolean isXATransaction() {
0268:                return _enableXA;
0269:            }
0270:
0271:            /**
0272:             * Returns the max idle time.
0273:             */
0274:            public long getMaxIdleTime() {
0275:                if (Long.MAX_VALUE / 2 <= _maxIdleTime)
0276:                    return -1;
0277:                else
0278:                    return _maxIdleTime;
0279:            }
0280:
0281:            /**
0282:             * Sets the max idle time.
0283:             */
0284:            public void setMaxIdleTime(long maxIdleTime) {
0285:                if (maxIdleTime < 0)
0286:                    _maxIdleTime = Long.MAX_VALUE / 2;
0287:                else
0288:                    _maxIdleTime = maxIdleTime;
0289:            }
0290:
0291:            /**
0292:             * Returns the max idle count.
0293:             */
0294:            public int getMaxIdleCount() {
0295:                return _maxIdleCount;
0296:            }
0297:
0298:            /**
0299:             * Sets the max idle count.
0300:             */
0301:            public void setMaxIdleCount(int maxIdleCount) {
0302:                if (maxIdleCount < 0)
0303:                    _maxIdleCount = 0;
0304:                else
0305:                    _maxIdleCount = maxIdleCount;
0306:            }
0307:
0308:            /**
0309:             * Returns the max active time.
0310:             */
0311:            public long getMaxActiveTime() {
0312:                if (Long.MAX_VALUE / 2 <= _maxActiveTime)
0313:                    return -1;
0314:                else
0315:                    return _maxActiveTime;
0316:            }
0317:
0318:            /**
0319:             * Sets the max active time.
0320:             */
0321:            public void setMaxActiveTime(long maxActiveTime) {
0322:                if (maxActiveTime < 0)
0323:                    _maxActiveTime = Long.MAX_VALUE / 2;
0324:                else
0325:                    _maxActiveTime = maxActiveTime;
0326:            }
0327:
0328:            /**
0329:             * Returns the max pool time.
0330:             */
0331:            public long getMaxPoolTime() {
0332:                if (Long.MAX_VALUE / 2 <= _maxPoolTime)
0333:                    return -1;
0334:                else
0335:                    return _maxPoolTime;
0336:            }
0337:
0338:            /**
0339:             * Sets the max pool time.
0340:             */
0341:            public void setMaxPoolTime(long maxPoolTime) {
0342:                if (maxPoolTime < 0)
0343:                    _maxPoolTime = Long.MAX_VALUE / 2;
0344:                else
0345:                    _maxPoolTime = maxPoolTime;
0346:            }
0347:
0348:            /**
0349:             * Sets the max number of connections
0350:             */
0351:            public void setMaxConnections(int maxConnections)
0352:                    throws ConfigException {
0353:                if (maxConnections == 0)
0354:                    throw new ConfigException(L
0355:                            .l("max-connections '0' must be at least 1."));
0356:
0357:                _maxConnections = maxConnections;
0358:
0359:                if (maxConnections < 0)
0360:                    _maxConnections = Integer.MAX_VALUE / 2;
0361:            }
0362:
0363:            /**
0364:             * Gets the maximum number of connections
0365:             */
0366:            public int getMaxConnections() {
0367:                if (_maxConnections < Integer.MAX_VALUE / 2)
0368:                    return _maxConnections;
0369:                else
0370:                    return -1;
0371:            }
0372:
0373:            /**
0374:             * Sets the time to wait for connections
0375:             */
0376:            public void setConnectionWaitTime(Period waitTime) {
0377:                _connectionWaitTime = waitTime.getPeriod();
0378:
0379:                if (_connectionWaitTime < 0)
0380:                    _connectionWaitTime = Long.MAX_VALUE / 2;
0381:
0382:                _connectionWaitCount = _connectionWaitTime / 1000;
0383:            }
0384:
0385:            /**
0386:             * Sets the time to wait for connections
0387:             */
0388:            public long getConnectionWaitTime() {
0389:                if (_connectionWaitTime < Long.MAX_VALUE / 2)
0390:                    return _connectionWaitTime;
0391:                else
0392:                    return -1;
0393:            }
0394:
0395:            /**
0396:             * Sets the max number of overflow connections
0397:             */
0398:            public void setMaxOverflowConnections(int maxOverflowConnections) {
0399:                _maxOverflowConnections = maxOverflowConnections;
0400:            }
0401:
0402:            /**
0403:             * Gets the max number of overflow connections
0404:             */
0405:            public int getMaxOverflowConnections() {
0406:                return _maxOverflowConnections;
0407:            }
0408:
0409:            /**
0410:             * Sets the max number of connections simultaneously creating
0411:             */
0412:            public void setMaxCreateConnections(int maxConnections)
0413:                    throws ConfigException {
0414:                if (maxConnections == 0)
0415:                    throw new ConfigException(
0416:                            L
0417:                                    .l("max-create-connections '0' must be at least 1."));
0418:
0419:                _maxCreateConnections = maxConnections;
0420:
0421:                if (maxConnections < 0)
0422:                    _maxCreateConnections = Integer.MAX_VALUE / 2;
0423:
0424:            }
0425:
0426:            /**
0427:             * Gets the maximum number of connections simultaneously creating
0428:             */
0429:            public int getMaxCreateConnections() {
0430:                if (_maxCreateConnections < Integer.MAX_VALUE / 2)
0431:                    return _maxCreateConnections;
0432:                else
0433:                    return -1;
0434:            }
0435:
0436:            /**
0437:             * Initialize the connection manager.
0438:             */
0439:            public Object init(ManagedConnectionFactory mcf)
0440:                    throws ConfigException, ResourceException {
0441:                if (!_lifecycle.toInit())
0442:                    return null;
0443:
0444:                if (_name == null)
0445:                    _name = "connection-pool-" + _idGen++;
0446:
0447:                if (_tm == null)
0448:                    throw new ConfigException(
0449:                            L
0450:                                    .l("the connection manager needs a transaction manager."));
0451:
0452:                _idlePool = new IdlePoolSet(_maxIdleCount);
0453:
0454:                registerSelf();
0455:
0456:                _alarm = new WeakAlarm(this );
0457:
0458:                if (!(mcf instanceof  ValidatingManagedConnectionFactory)) {
0459:                    // never check
0460:                    _lastValidCheckTime = Long.MAX_VALUE / 2;
0461:                }
0462:
0463:                // recover any resources on startup
0464:                if (_enableXA) {
0465:                    Subject subject = null;
0466:                    ManagedConnection mConn = mcf.createManagedConnection(
0467:                            subject, null);
0468:
0469:                    try {
0470:                        XAResource xa = mConn.getXAResource();
0471:
0472:                        _tm.recover(xa);
0473:                    } catch (NotSupportedException e) {
0474:                        _enableXA = false;
0475:                        log.finer(e.toString());
0476:                    } catch (Throwable e) {
0477:                        log.log(Level.FINER, e.toString(), e);
0478:                    } finally {
0479:                        mConn.destroy();
0480:                    }
0481:                }
0482:
0483:                return mcf.createConnectionFactory(this );
0484:            }
0485:
0486:            /**
0487:             * start the connection manager.
0488:             */
0489:            public void start() {
0490:                if (!_lifecycle.toActive())
0491:                    return;
0492:
0493:                if (0 < _maxIdleTime && _maxIdleTime < 1000)
0494:                    _alarm.queue(1000);
0495:                else if (1000 < _maxIdleTime && _maxIdleTime < 60000)
0496:                    _alarm.queue(_maxIdleTime);
0497:                else
0498:                    _alarm.queue(60000);
0499:            }
0500:
0501:            /**
0502:             * Generates a connection id.
0503:             */
0504:            String generateId() {
0505:                return String.valueOf(_idCount++);
0506:            }
0507:
0508:            /**
0509:             * Allocates the connection.
0510:             *
0511:             * @return connection handle for EIS specific connection.
0512:             */
0513:            public Object allocateConnection(ManagedConnectionFactory mcf,
0514:                    ConnectionRequestInfo info) throws ResourceException {
0515:                Subject subject = null;
0516:
0517:                Object conn = allocate(mcf, subject, info);
0518:
0519:                synchronized (this ) {
0520:                    _connectionCountTotal++;
0521:                }
0522:
0523:                return conn;
0524:            }
0525:
0526:            /**
0527:             * Adds a connection to the idle pool.
0528:             */
0529:            void toIdle(PoolItem item) {
0530:                if (_pool.size() <= _maxConnections
0531:                        && !item.isConnectionError()) {
0532:                    ManagedConnection mConn = item.getManagedConnection();
0533:                    if (mConn != null) {
0534:                        try {
0535:                            mConn.cleanup();
0536:
0537:                            ManagedConnection oldIdleConn = null;
0538:
0539:                            synchronized (_idlePool) {
0540:                                long now = Alarm.getCurrentTime();
0541:
0542:                                if (_idlePool.size() == 0)
0543:                                    _lastIdlePoolEmptyTime = now;
0544:
0545:                                if (now - _lastIdlePoolEmptyTime < _maxIdleTime
0546:                                        && _idlePool.add(mConn)) {
0547:                                    return;
0548:                                } else {
0549:                                    _lastIdlePoolEmptyTime = now;
0550:                                }
0551:                            }
0552:                        } catch (Throwable e) {
0553:                            log.log(Level.FINE, e.toString(), e);
0554:                        } finally {
0555:                            synchronized (_pool) {
0556:                                _pool.notify();
0557:                            }
0558:                        }
0559:                    }
0560:                }
0561:
0562:                toDead(item);
0563:            }
0564:
0565:            /**
0566:             * Returns the delegated pool item.
0567:             */
0568:            public PoolItem getDelegatePoolItem(Xid xid) {
0569:                ArrayList<PoolItem> pool = _pool;
0570:
0571:                synchronized (pool) {
0572:                    int size = pool.size();
0573:                    for (int i = 0; i < size; i++) {
0574:                        PoolItem item = pool.get(i);
0575:
0576:                        if (xid.equals(item.getXid()))
0577:                            return item;
0578:                    }
0579:                }
0580:
0581:                return null;
0582:            }
0583:
0584:            //
0585:            // statistics
0586:            //
0587:
0588:            /**
0589:             * Returns the total connections.
0590:             */
0591:            public int getConnectionCount() {
0592:                return _pool.size();
0593:            }
0594:
0595:            /**
0596:             * Returns the idle connections.
0597:             */
0598:            public int getConnectionIdleCount() {
0599:                return _idlePool.size();
0600:            }
0601:
0602:            /**
0603:             * Returns the active connections.
0604:             */
0605:            public int getConnectionActiveCount() {
0606:                return _pool.size() - _idlePool.size();
0607:            }
0608:
0609:            /**
0610:             * Returns the total connections.
0611:             */
0612:            public long getConnectionCountTotal() {
0613:                return _connectionCountTotal;
0614:            }
0615:
0616:            /**
0617:             * Returns the total connections.
0618:             */
0619:            public long getConnectionCreateCountTotal() {
0620:                return _connectionCreateCountTotal;
0621:            }
0622:
0623:            /**
0624:             * Returns the total failed connections.
0625:             */
0626:            public long getConnectionFailCountTotal() {
0627:                return _connectionFailCountTotal;
0628:            }
0629:
0630:            /**
0631:             * Returns the last fail time
0632:             */
0633:            public Date getLastFailTime() {
0634:                return new Date(_lastFailTime);
0635:            }
0636:
0637:            /**
0638:             * Clears the idle connections in the pool.
0639:             */
0640:            public void clear() {
0641:                ArrayList<PoolItem> pool = _pool;
0642:
0643:                if (pool == null)
0644:                    return;
0645:
0646:                ArrayList<PoolItem> clearItems = new ArrayList<PoolItem>();
0647:
0648:                synchronized (_idlePool) {
0649:                    _idlePool.clear();
0650:                }
0651:
0652:                synchronized (pool) {
0653:                    clearItems.addAll(pool);
0654:
0655:                    pool.clear();
0656:                }
0657:
0658:                for (int i = 0; i < clearItems.size(); i++) {
0659:                    PoolItem poolItem = clearItems.get(i);
0660:
0661:                    try {
0662:                        poolItem.destroy();
0663:                    } catch (Throwable e) {
0664:                        log.log(Level.WARNING, e.toString(), e);
0665:                    }
0666:                }
0667:            }
0668:
0669:            /**
0670:             * Returns the transaction.
0671:             */
0672:            UserTransactionImpl getTransaction() {
0673:                return _tm.getUserTransaction();
0674:            }
0675:
0676:            /**
0677:             * Allocates a connection.
0678:             */
0679:            private Object allocate(ManagedConnectionFactory mcf,
0680:                    Subject subject, ConnectionRequestInfo info)
0681:                    throws ResourceException {
0682:                UserPoolItem userPoolItem = null;
0683:
0684:                try {
0685:                    UserTransactionImpl transaction = _tm.getUserTransaction();
0686:
0687:                    if (transaction == null)
0688:                        return allocatePool(mcf, subject, info, null)
0689:                                .allocateUserConnection();
0690:
0691:                    userPoolItem = transaction.allocate(mcf, subject, info);
0692:
0693:                    if (userPoolItem == null)
0694:                        userPoolItem = allocatePool(mcf, subject, info, null);
0695:
0696:                    return userPoolItem.allocateUserConnection();
0697:                } catch (RuntimeException e) {
0698:                    if (userPoolItem != null)
0699:                        userPoolItem.close();
0700:
0701:                    throw e;
0702:                } catch (ResourceException e) {
0703:                    if (userPoolItem != null)
0704:                        userPoolItem.close();
0705:
0706:                    throw e;
0707:                } catch (Throwable e) {
0708:                    if (userPoolItem != null)
0709:                        userPoolItem.close();
0710:
0711:                    throw new ResourceException(e);
0712:                }
0713:            }
0714:
0715:            /**
0716:             * Allocates a connection.
0717:             */
0718:            UserPoolItem allocatePool(ManagedConnectionFactory mcf,
0719:                    Subject subject, ConnectionRequestInfo info,
0720:                    UserPoolItem oldUserItem) throws ResourceException {
0721:                long timeoutCount = _connectionWaitCount;
0722:
0723:                while (_lifecycle.isActive()) {
0724:                    UserPoolItem userPoolItem = allocateIdle(mcf, subject,
0725:                            info, oldUserItem);
0726:
0727:                    if (userPoolItem != null)
0728:                        return userPoolItem;
0729:
0730:                    userPoolItem = create(mcf, subject, info, false,
0731:                            oldUserItem);
0732:
0733:                    if (userPoolItem != null)
0734:                        return userPoolItem;
0735:
0736:                    if (timeoutCount-- < 0)
0737:                        break;
0738:                }
0739:
0740:                if (!_lifecycle.isActive())
0741:                    throw new IllegalStateException(L
0742:                            .l("connection pool closed"));
0743:
0744:                UserPoolItem userPoolItem = create(mcf, subject, info, true,
0745:                        oldUserItem);
0746:
0747:                if (userPoolItem == null)
0748:                    throw new NullPointerException(
0749:                            L
0750:                                    .l("ConnectionPool create should not return a null PoolItem for overflow connections."));
0751:
0752:                return userPoolItem;
0753:            }
0754:
0755:            /**
0756:             * Allocates a connection from the idle pool.
0757:             */
0758:            private UserPoolItem allocateIdle(ManagedConnectionFactory mcf,
0759:                    Subject subject, ConnectionRequestInfo info,
0760:                    UserPoolItem oldUserItem) throws ResourceException {
0761:                while (_lifecycle.isActive()) {
0762:                    ManagedConnection mConn;
0763:
0764:                    long now = Alarm.getCurrentTime();
0765:
0766:                    if (_lastValidCheckTime + 1000L < now) {
0767:                        _lastValidCheckTime = now;
0768:
0769:                        if (mcf instanceof  ValidatingManagedConnectionFactory) {
0770:                            ValidatingManagedConnectionFactory vmcf;
0771:                            vmcf = (ValidatingManagedConnectionFactory) mcf;
0772:
0773:                            validate(vmcf);
0774:                        }
0775:                    }
0776:
0777:                    // asks the Driver's ManagedConnectionFactory to match an
0778:                    // idle connection
0779:                    synchronized (_idlePool) {
0780:                        mConn = mcf.matchManagedConnections(_idlePool, subject,
0781:                                info);
0782:
0783:                        // If there are no more idle connections, return null
0784:                        if (mConn == null)
0785:                            return null;
0786:
0787:                        _idlePool.remove(mConn);
0788:                    }
0789:
0790:                    PoolItem poolItem = null;
0791:
0792:                    synchronized (_pool) {
0793:                        for (int i = _pool.size() - 1; i >= 0; i--) {
0794:                            poolItem = _pool.get(i);
0795:
0796:                            if (poolItem.getManagedConnection() == mConn)
0797:                                break;
0798:                        }
0799:                    }
0800:
0801:                    if (poolItem == null)
0802:                        throw new IllegalStateException(L.l(
0803:                                "No matching PoolItem found for {0}", mConn));
0804:
0805:                    UserPoolItem userPoolItem = null;
0806:
0807:                    // Ensure the connection is still valid
0808:                    userPoolItem = poolItem
0809:                            .toActive(subject, info, oldUserItem);
0810:                    if (userPoolItem != null)
0811:                        return userPoolItem;
0812:
0813:                    toDead(poolItem);
0814:                }
0815:
0816:                return null;
0817:            }
0818:
0819:            /**
0820:             * Validates the pool.
0821:             */
0822:            private void validate(ValidatingManagedConnectionFactory mcf) {
0823:                Set invalid = null;
0824:                /*
0825:                synchronized (_idlePool) {
0826:                } */
0827:            }
0828:
0829:            /**
0830:             * Creates a new connection.
0831:             */
0832:            private UserPoolItem create(ManagedConnectionFactory mcf,
0833:                    Subject subject, ConnectionRequestInfo info,
0834:                    boolean isOverflow, UserPoolItem oldUserItem)
0835:                    throws ResourceException {
0836:                synchronized (_pool) {
0837:                    int size = _pool.size();
0838:
0839:                    if (isOverflow
0840:                            && _maxConnections + _maxOverflowConnections <= _createCount
0841:                                    + size) {
0842:                        throw new ResourceException(
0843:                                L
0844:                                        .l("Connection pool is full.  Can't allocate connection."));
0845:                    }
0846:                    // if the pool is full, don't create, and wait
0847:                    else if (!isOverflow
0848:                            && (_maxConnections <= _createCount + size || _maxCreateConnections <= _createCount)) {
0849:                        try {
0850:                            _pool.wait(1000);
0851:                        } catch (Exception e) {
0852:                            log.log(Level.FINE, e.toString(), e);
0853:                        }
0854:
0855:                        return null;
0856:                    }
0857:
0858:                    _createCount++;
0859:                }
0860:
0861:                PoolItem poolItem = null;
0862:                try {
0863:                    ManagedConnection mConn = mcf.createManagedConnection(
0864:                            subject, info);
0865:
0866:                    if (mConn == null)
0867:                        throw new ResourceException(
0868:                                L
0869:                                        .l(
0870:                                                "'{0}' did not return a connection from createManagedConnection",
0871:                                                mcf));
0872:
0873:                    poolItem = new PoolItem(this , mcf, mConn);
0874:
0875:                    UserPoolItem userPoolItem;
0876:
0877:                    // Ensure the connection is still valid
0878:                    userPoolItem = poolItem
0879:                            .toActive(subject, info, oldUserItem);
0880:                    if (userPoolItem != null) {
0881:                        synchronized (this ) {
0882:                            _connectionCreateCountTotal++;
0883:                        }
0884:
0885:                        return userPoolItem;
0886:                    }
0887:
0888:                    throw new IllegalStateException(L.l(
0889:                            "Connection '{0}' was not valid on creation",
0890:                            poolItem));
0891:                } catch (RuntimeException e) {
0892:                    synchronized (this ) {
0893:                        _connectionFailCountTotal++;
0894:                        _lastFailTime = Alarm.getCurrentTime();
0895:                    }
0896:
0897:                    throw e;
0898:                } catch (ResourceException e) {
0899:                    synchronized (this ) {
0900:                        _connectionFailCountTotal++;
0901:                        _lastFailTime = Alarm.getCurrentTime();
0902:                    }
0903:
0904:                    throw e;
0905:                } finally {
0906:                    synchronized (_pool) {
0907:                        _createCount--;
0908:
0909:                        if (poolItem != null)
0910:                            _pool.add(poolItem);
0911:
0912:                        _pool.notify();
0913:                    }
0914:                }
0915:            }
0916:
0917:            /**
0918:             * Alarm listener.
0919:             */
0920:            public void handleAlarm(Alarm alarm) {
0921:                if (!_lifecycle.isActive())
0922:                    return;
0923:
0924:                try {
0925:                    long now = Alarm.getCurrentTime();
0926:
0927:                    _alarmConnections.clear();
0928:
0929:                    synchronized (_pool) {
0930:                        _alarmConnections.addAll(_pool);
0931:                    }
0932:
0933:                    for (int i = _alarmConnections.size() - 1; i >= 0; i--) {
0934:                        PoolItem item = _alarmConnections.get(i);
0935:
0936:                        if (!item.isValid())
0937:                            toDead(item);
0938:                    }
0939:
0940:                    _alarmConnections.clear();
0941:                } finally {
0942:                    if (!_lifecycle.isActive()) {
0943:                    } else if (0 < _maxIdleTime && _maxIdleTime < 1000)
0944:                        _alarm.queue(1000);
0945:                    else if (1000 < _maxIdleTime && _maxIdleTime < 60000)
0946:                        _alarm.queue(_maxIdleTime);
0947:                    else
0948:                        _alarm.queue(60000);
0949:                }
0950:            }
0951:
0952:            /**
0953:             * Removes a connection
0954:             */
0955:            void toDead(PoolItem item) {
0956:                synchronized (_idlePool) {
0957:                    _idlePool.remove(item.getManagedConnection());
0958:                }
0959:
0960:                synchronized (_pool) {
0961:                    _pool.remove(item);
0962:                    _pool.notify();
0963:                }
0964:
0965:                try {
0966:                    item.destroy();
0967:                } catch (Throwable e) {
0968:                    log.log(Level.WARNING, e.toString(), e);
0969:                }
0970:            }
0971:
0972:            /*
0973:             * Removes a connection from the pool.
0974:             */
0975:            public void markForPoolRemoval(ManagedConnectionImpl mConn) {
0976:                for (PoolItem poolItem : _pool) {
0977:                    if (poolItem.getManagedConnection() == mConn) {
0978:                        poolItem.setConnectionError();
0979:                        break;
0980:                    }
0981:                }
0982:            }
0983:
0984:            /**
0985:             * Stops the manager.
0986:             */
0987:            public void stop() {
0988:                if (!_lifecycle.toStop())
0989:                    return;
0990:
0991:                if (_alarm != null)
0992:                    _alarm.dequeue();
0993:            }
0994:
0995:            /**
0996:             * Destroys the manager.
0997:             */
0998:            public void destroy() {
0999:                stop();
1000:
1001:                if (!_lifecycle.toDestroy())
1002:                    return;
1003:
1004:                ArrayList<PoolItem> pool = _pool;
1005:
1006:                synchronized (pool) {
1007:                    for (int i = 0; i < pool.size(); i++) {
1008:                        PoolItem poolItem = pool.get(i);
1009:
1010:                        try {
1011:                            poolItem.destroy();
1012:                        } catch (Throwable e) {
1013:                            log.log(Level.WARNING, e.toString(), e);
1014:                        }
1015:                    }
1016:
1017:                    pool.clear();
1018:                    _idlePool.clear();
1019:                }
1020:            }
1021:
1022:            public String toString() {
1023:                return "ConnectionPool[" + getName() + "]";
1024:            }
1025:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.