connectionpool.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,090 行 · 第 1/2 页
JAVA
1,090 行
} /** * Generates a connection id. */ String generateId() { return String.valueOf(_idCount++); } /** * Allocates the connection. * * @return connection handle for EIS specific connection. */ public Object allocateConnection(ManagedConnectionFactory mcf, ConnectionRequestInfo info) throws ResourceException { Subject subject = null; Object conn = allocate(mcf, subject, info); synchronized (this) { _connectionCountTotal++; } return conn; } /** * Adds a connection to the idle pool. */ void toIdle(PoolItem item) { if (_pool.size() <= _maxConnections && ! item.isConnectionError()) { ManagedConnection mConn = item.getManagedConnection(); if (mConn != null) { try { mConn.cleanup(); ManagedConnection oldIdleConn = null; synchronized (_idlePool) { long now = Alarm.getCurrentTime(); if (_idlePool.size() == 0) _lastIdlePoolEmptyTime = now; if (now - _lastIdlePoolEmptyTime < _maxIdleTime && _idlePool.add(mConn)) { return; } else { _lastIdlePoolEmptyTime = now; } } } catch (Throwable e) { log.log(Level.FINE, e.toString(), e); } finally { synchronized (_pool) { _pool.notify(); } } } } toDead(item); } /** * Returns the delegated pool item. */ public PoolItem getDelegatePoolItem(Xid xid) { ArrayList<PoolItem> pool = _pool; synchronized (pool) { int size = pool.size(); for (int i = 0; i < size; i++) { PoolItem item = pool.get(i); if (xid.equals(item.getXid())) return item; } } return null; } // // statistics // /** * Returns the total connections. */ public int getConnectionCount() { return _pool.size(); } /** * Returns the idle connections. */ public int getConnectionIdleCount() { return _idlePool.size(); } /** * Returns the active connections. */ public int getConnectionActiveCount() { return _pool.size() - _idlePool.size(); } /** * Returns the total connections. */ public long getConnectionCountTotal() { return _connectionCountTotal; } /** * Returns the total connections. */ public long getConnectionCreateCountTotal() { return _connectionCreateCountTotal; } /** * Returns the total failed connections. */ public long getConnectionFailCountTotal() { return _connectionFailCountTotal; } /** * Returns the last fail time */ public Date getLastFailTime() { return new Date(_lastFailTime); } /** * Clears the idle connections in the pool. */ public void clear() { ArrayList<PoolItem> pool = _pool; if (pool == null) return; ArrayList<PoolItem> clearItems = new ArrayList<PoolItem>(); synchronized (_idlePool) { _idlePool.clear(); } synchronized (pool) { clearItems.addAll(pool); pool.clear(); } for (int i = 0; i < clearItems.size(); i++) { PoolItem poolItem = clearItems.get(i); try { poolItem.destroy(); } catch (Throwable e) { log.log(Level.WARNING, e.toString(), e); } } } /** * Returns the transaction. */ UserTransactionImpl getTransaction() { return _tm.getUserTransaction(); } /** * Allocates a connection. */ private Object allocate(ManagedConnectionFactory mcf, Subject subject, ConnectionRequestInfo info) throws ResourceException { UserPoolItem userPoolItem = null; try { UserTransactionImpl transaction = _tm.getUserTransaction(); if (transaction == null) return allocatePool(mcf, subject, info, null).allocateUserConnection(); userPoolItem = transaction.allocate(mcf, subject, info); if (userPoolItem == null) userPoolItem = allocatePool(mcf, subject, info, null); return userPoolItem.allocateUserConnection(); } catch (RuntimeException e) { if (userPoolItem != null) userPoolItem.close(); throw e; } catch (ResourceException e) { if (userPoolItem != null) userPoolItem.close(); throw e; } catch (Throwable e) { if (userPoolItem != null) userPoolItem.close(); throw new ResourceException(e); } } /** * Allocates a connection. */ UserPoolItem allocatePool(ManagedConnectionFactory mcf, Subject subject, ConnectionRequestInfo info, UserPoolItem oldUserItem) throws ResourceException { long timeoutCount = _connectionWaitCount; while (_lifecycle.isActive()) { UserPoolItem userPoolItem = allocateIdle(mcf, subject, info, oldUserItem); if (userPoolItem != null) return userPoolItem; userPoolItem = create(mcf, subject, info, false, oldUserItem); if (userPoolItem != null) return userPoolItem; if (timeoutCount-- < 0) break; } if (! _lifecycle.isActive()) throw new IllegalStateException(L.l("connection pool closed")); UserPoolItem userPoolItem = create(mcf, subject, info, true, oldUserItem); if (userPoolItem == null) throw new NullPointerException(L.l("ConnectionPool create should not return a null PoolItem for overflow connections.")); return userPoolItem; } /** * Allocates a connection from the idle pool. */ private UserPoolItem allocateIdle(ManagedConnectionFactory mcf, Subject subject, ConnectionRequestInfo info, UserPoolItem oldUserItem) throws ResourceException { while (_lifecycle.isActive()) { ManagedConnection mConn; long now = Alarm.getCurrentTime(); if (_lastValidCheckTime + 1000L < now) { _lastValidCheckTime = now; if (mcf instanceof ValidatingManagedConnectionFactory) { ValidatingManagedConnectionFactory vmcf; vmcf = (ValidatingManagedConnectionFactory) mcf; validate(vmcf); } } // asks the Driver's ManagedConnectionFactory to match an // idle connection synchronized (_idlePool) { mConn = mcf.matchManagedConnections(_idlePool, subject, info); // If there are no more idle connections, return null if (mConn == null) return null; _idlePool.remove(mConn); } PoolItem poolItem = null; synchronized (_pool) { for (int i = _pool.size() - 1; i >= 0; i--) { poolItem = _pool.get(i); if (poolItem.getManagedConnection() == mConn) break; } } if (poolItem == null) throw new IllegalStateException(L.l("No matching PoolItem found for {0}", mConn)); UserPoolItem userPoolItem = null; // Ensure the connection is still valid userPoolItem = poolItem.toActive(subject, info, oldUserItem); if (userPoolItem != null) return userPoolItem; toDead(poolItem); } return null; } /** * Validates the pool. */ private void validate(ValidatingManagedConnectionFactory mcf) { Set invalid = null; /* synchronized (_idlePool) { } */ } /** * Creates a new connection. */ private UserPoolItem create(ManagedConnectionFactory mcf, Subject subject, ConnectionRequestInfo info, boolean isOverflow, UserPoolItem oldUserItem) throws ResourceException { synchronized (_pool) { int size = _pool.size(); if (isOverflow && _maxConnections + _maxOverflowConnections <= _createCount + size) { throw new ResourceException(L.l("Connection pool is full. Can't allocate connection.")); } // if the pool is full, don't create, and wait else if (! isOverflow && (_maxConnections <= _createCount + size || _maxCreateConnections <= _createCount)) { try { _pool.wait(1000); } catch (Exception e) { log.log(Level.FINE, e.toString(), e); } return null; } _createCount++; } PoolItem poolItem = null; try { ManagedConnection mConn = mcf.createManagedConnection(subject, info); if (mConn == null) throw new ResourceException(L.l("'{0}' did not return a connection from createManagedConnection", mcf)); poolItem = new PoolItem(this, mcf, mConn); UserPoolItem userPoolItem; // Ensure the connection is still valid userPoolItem = poolItem.toActive(subject, info, oldUserItem); if (userPoolItem != null) { synchronized (this) { _connectionCreateCountTotal++; } return userPoolItem; } throw new IllegalStateException(L.l("Connection '{0}' was not valid on creation", poolItem)); } catch (RuntimeException e) { synchronized (this) { _connectionFailCountTotal++; _lastFailTime = Alarm.getCurrentTime(); } throw e; } catch (ResourceException e) { synchronized (this) { _connectionFailCountTotal++; _lastFailTime = Alarm.getCurrentTime(); } throw e; } finally { synchronized (_pool) { _createCount--; if (poolItem != null) _pool.add(poolItem); _pool.notify(); } } } /** * Alarm listener. */ public void handleAlarm(Alarm alarm) { if (! _lifecycle.isActive()) return; try { long now = Alarm.getCurrentTime(); _alarmConnections.clear(); synchronized (_pool) { _alarmConnections.addAll(_pool); } for (int i = _alarmConnections.size() - 1; i >= 0; i--) { PoolItem item = _alarmConnections.get(i); if (! item.isValid()) toDead(item); } _alarmConnections.clear(); } finally { if (! _lifecycle.isActive()) { } else if (0 < _maxIdleTime && _maxIdleTime < 1000) _alarm.queue(1000); else if (1000 < _maxIdleTime && _maxIdleTime < 60000) _alarm.queue(_maxIdleTime); else _alarm.queue(60000); } } /** * Removes a connection */ void toDead(PoolItem item) { synchronized (_idlePool) { _idlePool.remove(item.getManagedConnection()); } synchronized (_pool) { _pool.remove(item); _pool.notify(); } try { item.destroy(); } catch (Throwable e) { log.log(Level.WARNING, e.toString(), e); } } /* * Removes a connection from the pool. */ public void markForPoolRemoval(ManagedConnectionImpl mConn) { for (PoolItem poolItem : _pool) { if (poolItem.getManagedConnection() == mConn) { poolItem.setConnectionError(); break; } } } /** * Stops the manager. */ public void stop() { if (! _lifecycle.toStop()) return; if (_alarm != null) _alarm.dequeue(); } /** * Destroys the manager. */ public void destroy() { stop(); if (! _lifecycle.toDestroy()) return; ArrayList<PoolItem> pool = _pool; synchronized (pool) { for (int i = 0; i < pool.size(); i++) { PoolItem poolItem = pool.get(i); try { poolItem.destroy(); } catch (Throwable e) { log.log(Level.WARNING, e.toString(), e); } } pool.clear(); _idlePool.clear(); } } public String toString() { return "ConnectionPool[" + getName() + "]"; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?