/** Allocates a connection. */ private Object allocateConnection( ManagedConnectionFactory mcf, Subject subject, ConnectionRequestInfo info) throws ResourceException { UserPoolItem userPoolItem = null; try { while (true) { userPoolItem = null; UserTransactionImpl transaction = _tm.getUserTransaction(); if (transaction != null) userPoolItem = allocateShared(transaction, mcf, subject, info); if (userPoolItem == null) userPoolItem = allocatePoolConnection(mcf, subject, info, null); Object userConn; userConn = userPoolItem.allocateUserConnection(); if (userConn != null) { userPoolItem = null; return userConn; } userPoolItem.close(); } } finally { if (userPoolItem != null) userPoolItem.close(); } }
/** Try to share the connection. */ boolean share(UserPoolItem userPoolItem) { if (this == userPoolItem.getOwnPoolItem()) return true; else if (_mConn == null) // already closed return false; else if (!_cm.isShareable()) // not shareable return false; else if (_mcf != userPoolItem.getManagedConnectionFactory()) return false; else if (_subject != userPoolItem.getSubject()) return false; else if (_requestInfo != userPoolItem.getInfo()) return false; else if (_hasConnectionError) // had a fatal error return false; // skip for now if (true) return false; userPoolItem.associate(this, _mcf, _subject, _requestInfo); return true; }
/** * Make this connection active. * * @return true if the pool item is valid, false if it should be removed. */ synchronized UserPoolItem toActive( Subject subject, ConnectionRequestInfo info, UserPoolItem oldPoolItem) throws ResourceException { long now = Alarm.getCurrentTime(); long maxIdleTime = _cm.getMaxIdleTime(); long maxPoolTime = _cm.getMaxPoolTime(); if (_hasConnectionError) return null; else if (0 < maxIdleTime && _poolEventTime + maxIdleTime < now) return null; else if (0 < maxPoolTime && _poolStartTime + maxPoolTime < now) return null; else if (_shareHead != null) throw new IllegalStateException(L.l("trying to activate active pool item.")); _poolEventTime = now; _isXATransaction = _xaResource != null; // disable LT-optim by default UserPoolItem userPoolItem = null; if (oldPoolItem != null) { Object uConn = oldPoolItem.getUserConnection(); if (uConn != null) _mConn.associateConnection(uConn); oldPoolItem.associatePoolItem(this); userPoolItem = oldPoolItem; } else userPoolItem = new UserPoolItem(_cm, this); if (!isValid(subject, info, userPoolItem)) return null; _subject = subject; _requestInfo = info; userPoolItem.associate(this, _mcf, subject, info); if (log.isLoggable(Level.FINE)) log.fine("allocate " + this); if (_cm.getSaveAllocationStackTrace()) _allocationStackTrace = new IllegalStateException(L.l("Connection {0} allocation stack trace", this)); return userPoolItem; }
private void fillIdlePool() { int count = _minIdleCount; try { while (_connectionPool.size() < _minIdleCount && count-- >= 0 && _lifecycle.isActive()) { Subject subject = null; ConnectionRequestInfo info = null; UserPoolItem userPoolItem; userPoolItem = createConnection(_mcf, subject, info, null); if (userPoolItem != null) userPoolItem.toIdle(); } } catch (Exception e) { e.printStackTrace(); log.log(Level.FINE, e.toString(), e); } }
/** Returns true for a valid connection. */ boolean isValid(Subject subject, ConnectionRequestInfo requestInfo, UserPoolItem userPoolItem) { try { ManagedConnection mConn = getManagedConnection(); if (mConn == null) return false; Object userConn = userPoolItem.getUserConnection(); if (userConn == null) { userConn = mConn.getConnection(subject, requestInfo); userPoolItem.setUserConnection(userConn); } return userConn != null; } catch (ResourceException e) { log.log(Level.WARNING, e.toString(), e); return false; } }
/** * Use the item only if it's already been used for the current transaction and is available. * allocateXA returns the same connection for the following case: * * <pre> * UserTransaction.begin(); * * conn = ds.getConnection(); * ... * conn.close(); * * conn = ds.getConnection(); * ... * conn.close(); * </pre> * * <p>Nested connections are not reused. * * @param xid the current transaction id * @return true if the pool item has been allocated */ UserPoolItem allocateXA( ManagedConnectionFactory mcf, Subject subject, ConnectionRequestInfo info) { if (_mConn == null) // already closed return null; else if (_subject != subject) return null; else if (_requestInfo != info) return null; else if (_mcf != mcf) return null; else if (_shareHead != null && !_cm.isShareable()) // is currently in use return null; /* server/14g9, #2708 else if (_hasConnectionError) // had a fatal error return null; */ if (log.isLoggable(Level.FINER)) log.finer("sharing xa-pool item: " + this); UserPoolItem userPoolItem = new UserPoolItem(_cm); userPoolItem.associate(this, _mcf, _subject, _requestInfo); return userPoolItem; }
/** Restores the delegation for the entire chain. */ private void clearXid() { _xid = null; UserPoolItem shareHead = _shareHead; _shareHead = null; ManagedPoolItem xaPtr = _xaNext; _xaHead = null; _xaNext = null; UserPoolItem assignedUserItem = null; for (UserPoolItem ptr = shareHead; ptr != null; ptr = ptr.getShareNext()) { if (ptr.getOwnPoolItem() == this) { assignedUserItem = ptr; break; } } for (UserPoolItem ptr = shareHead; ptr != null; ptr = ptr.getShareNext()) { if (assignedUserItem == null && ptr.getOwnPoolItem() == null) { ptr.associatePoolItem(this); assignedUserItem = ptr; } try { ptr.reassociatePoolItem(); } catch (Throwable e) { log.log(Level.WARNING, e.toString(), e); } } while (xaPtr != null) { ManagedPoolItem next = xaPtr._xaNext; xaPtr._xaNext = null; xaPtr._xaHead = null; xaPtr.clearXid(); xaPtr = next; } if (assignedUserItem != null) { // _shareHead = assignedUserItem; // _shareHead.setShareNext(null); } else if (_hasConnectionError) { destroy(); } else { toIdle(); } }
/** * Notifies that an application has closed the connection. * * <p>Remove and close the UserPoolItem associated with the PoolItem. If it's the last * UserPoolItem, move to the idle state. */ public void connectionClosed(ConnectionEvent event) { Object handle = event.getConnectionHandle(); if (!_hasConnectionError && handle == null && _shareHead != null) { log.fine( L.l( "JCA close event '{0}' for {1} did not have a connection handle. Please notify the JCA resource provider.", event, _mConn)); } UserPoolItem ptr = _shareHead; UserPoolItem prev = null; while (ptr != null) { UserPoolItem next = ptr.getShareNext(); Object userConn = ptr.getUserConnection(); if (userConn == handle || handle == null) { if (prev != null) prev.setShareNext(next); else _shareHead = next; ptr.close(); } else prev = ptr; ptr = next; } if (_shareHead == null) { toIdle(); return; } }
/** Closes the connection. */ void destroy() { ManagedConnection mConn = _mConn; _mConn = null; UserTransactionImpl transaction = _transaction; _transaction = null; if (mConn == null) return; _cm.removeItem(this, mConn); UserPoolItem userItem = _shareHead; if (log.isLoggable(Level.FINE)) log.fine("connection pool destroy " + this); try { while (userItem != null) { UserPoolItem next = userItem.getShareNext(); userItem.close(); userItem = next; } if (transaction != null) transaction.delistPoolItem(this, XAResource.TMFAIL); } catch (Throwable e) { log.log(Level.FINE, e.toString(), e); } try { mConn.destroy(); } catch (Exception e) { log.log(Level.FINE, e.toString(), e); } finally { _cm.getConnectionTimeProbe().end(_connectionStartTime); } }