poolitem.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,127 行 · 第 1/2 页
JAVA
1,127 行
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */package com.caucho.jca;import com.caucho.log.Log;import com.caucho.util.Alarm;import com.caucho.util.L10N;import javax.resource.NotSupportedException;import javax.resource.ResourceException;import javax.resource.spi.ConnectionEvent;import javax.resource.spi.ConnectionEventListener;import javax.resource.spi.ConnectionRequestInfo;import javax.resource.spi.LocalTransaction;import javax.resource.spi.ManagedConnection;import javax.resource.spi.ManagedConnectionFactory;import javax.security.auth.Subject;import javax.transaction.xa.XAException;import javax.transaction.xa.XAResource;import javax.transaction.xa.Xid;import java.util.logging.Level;import java.util.logging.Logger;/** * Implementation of the connection manager manager. */class PoolItem implements ConnectionEventListener, XAResource { private static final L10N L = new L10N(PoolItem.class); private static final Logger log = Log.open(PoolItem.class); private ConnectionPool _cm; private ManagedConnectionFactory _mcf; private ManagedConnection _mConn; private UserTransactionImpl _transaction; private String _id; private XAResource _xaResource; private LocalTransaction _localTransaction; private int _defaultTransactionTimeout; private int _transactionTimeout; private Subject _subject; private ConnectionRequestInfo _requestInfo; final Object _shareLock = new Object(); // The head shared connection for transaction // The UserPoolItem code is responsible for this field UserPoolItem _shareHead; // The other pool items joined transaction private PoolItem _xaHead; private PoolItem _xaNext; private boolean _hasConnectionError; private long _poolStartTime; private long _poolEventTime; private Xid _xid; private int _endFlags = -1; // flag forcing an XA transaction (for the local transaction optimization) private boolean _isXATransaction = true; // true if in local transaction private boolean _isLocalTransaction; private IllegalStateException _allocationStackTrace; public PoolItem(ConnectionPool cm, ManagedConnectionFactory mcf, ManagedConnection conn) { _cm = cm; _id = _cm.generateId(); _mcf = mcf; _mConn = conn; _poolStartTime = Alarm.getCurrentTime(); _poolEventTime = Alarm.getCurrentTime(); // Gets the resource object from the driver try { if (cm.isXATransaction()) { XAResource xaResource = conn.getXAResource(); try { _defaultTransactionTimeout = xaResource.getTransactionTimeout(); } catch (Throwable e) { log.log(Level.FINE, e.toString(), e); } _xaResource = xaResource; } } catch (NotSupportedException e) { _cm.setXATransaction(false); log.log(Level.FINER, e.toString(), e); } catch (Exception e) { log.log(Level.FINE, e.toString(), e); } if (_xaResource == null) _isXATransaction = false; // Gets the local transaction from the driver try { if (_cm.isLocalTransaction()) _localTransaction = conn.getLocalTransaction(); } catch (NotSupportedException e) { _cm.setLocalTransaction(false); log.log(Level.FINE, e.toString(), e); } catch (Exception e) { log.log(Level.FINE, e.toString(), e); } _mConn.addConnectionEventListener(this); if (log.isLoggable(Level.FINE)) log.fine("create: " + this + "(active:" + _cm.getConnectionActiveCount() + ", total:" + _cm.getConnectionCount() + ")"); } /** * Sets the subject. */ public void setSubject(Subject subject) { _subject = subject; } /** * Sets the info. */ public void setInfo(ConnectionRequestInfo info) { _requestInfo = info; } /** * Returns true if the connection is active. */ public boolean isActive() { return _shareHead != null; } /** * Returns true if the connection is dead */ public boolean isDead() { return _mConn == null; } /** * Returns the time of the last event. */ public long getEventTime() { return _poolEventTime; } /** * Returns the time the connection was first used. */ public long getStartTime() { return _poolStartTime; } /** * Sets the item's transaction. */ void setTransaction(UserTransactionImpl transaction) { _transaction = transaction; } /** * 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 userPoolItem) 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 if (userPoolItem != null) { Object uConn = userPoolItem.getUserConnection(); if (uConn != null) _mConn.associateConnection(uConn); userPoolItem.associatePoolItem(this); } 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; } /** * Checks if the pool item is still valid. * * @return true if the pool item is valid, false if it should be removed. */ boolean isValid() { synchronized (this) { long now = Alarm.getCurrentTime(); long maxIdleTime = _cm.getMaxIdleTime(); long maxPoolTime = _cm.getMaxPoolTime(); long maxActiveTime = _cm.getMaxActiveTime(); boolean isActive = isActive() || _xid != null; boolean isDead = false; if (! isActive && _hasConnectionError) { isDead = true; log.fine("closing pool item from connection error:" + this); } else if (! isActive && 0 < maxIdleTime && _poolEventTime + maxIdleTime < now) { isDead = true; log.fine("closing pool item from idle timeout:" + this); } else if (! isActive && 0 < maxPoolTime && _poolStartTime + maxPoolTime < now) { isDead = true; log.fine("closing pool item from pool timeout:" + this); } else if (isActive && 0 < maxActiveTime && _poolEventTime + maxActiveTime < now) { isDead = true; log.warning("closing pool item from active timeout:" + this); } if (isDead) { _hasConnectionError = true; return false; } else return true; } } /** * 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; } /** * Returns true if the tested pool item is the Xid leader. */ boolean isJoin(PoolItem item) { if (this == item) return false; else if (_xid != item._xid) return false; else if (_mcf != item._mcf) return false; else return true; } /** * 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; } /** * Returns the managed connection. */ ManagedConnection getManagedConnection() { return _mConn; } /** * Returns the user connection. */ /* Object getUserConnection() throws ResourceException { return _userPoolItem.getUserConnection(); } */ /** * Returns the user connection. */ Object allocateConnection() throws ResourceException { return _mConn.getConnection(_subject, _requestInfo); } /** * 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; } } /** * Returns the XA resource. */ void enableLocalTransactionOptimization(boolean enableOptimization) { if (_xaResource == null) _isXATransaction = false; else if (_localTransaction == null) _isXATransaction = true; else if (! _cm.isLocalTransactionOptimization()) _isXATransaction = true; else if (! _cm.isShareable()) _isXATransaction = true; else _isXATransaction = ! enableOptimization; } /** * Returns true if the pooled connection supports transactions. */ boolean supportsTransaction() { // server/164j return _xaResource != null || _localTransaction != null; } /** * Returns the XA resource. */ XAResource getXAResource() { return _xaResource; } /** * Returns the Xid resource. */ Xid getXid() { return _xid; } /** * Notifies that an application has closed the connection. */ public void connectionClosed(ConnectionEvent event) { boolean addIdle = false; 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)); } if (_shareHead == null) { toIdle(); return; } UserPoolItem userPoolItem = _shareHead; while (userPoolItem != null) { UserPoolItem next = userPoolItem.getShareNext(); Object userConn = userPoolItem.getUserConnection(); if (userConn == handle || handle == null) userPoolItem.close(); userPoolItem = next; } } /** * Notifies that a local transaction has started. */ public void localTransactionStarted(ConnectionEvent event) { if (_isLocalTransaction || _xid != null) throw new IllegalStateException(L.l("attempted to start local transaction while transaction is in progress.")); // server/30c4, #2627 _isLocalTransaction = true; } /** * Notifies that a local transaction has committed. */ public void localTransactionCommitted(ConnectionEvent event) { if (_xid != null) throw new IllegalStateException(L.l("attempted to commit() local transaction from an active XA transaction.")); else if (! _isLocalTransaction) throw new IllegalStateException(L.l("attempted to commit() with no active local transaction.")); // #2627, server/30c4 _isLocalTransaction = false; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?