managedconnectionimpl.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 903 行 · 第 1/2 页

JAVA
903
字号
/* * 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.sql;import com.caucho.log.Log;import com.caucho.sql.spy.SpyConnection;import com.caucho.sql.spy.SpyXAResource;import com.caucho.util.Alarm;import com.caucho.util.L10N;import com.caucho.util.LruCache;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.ManagedConnectionMetaData;import javax.security.auth.Subject;import javax.sql.PooledConnection;import javax.sql.XAConnection;import javax.transaction.xa.XAResource;import java.io.PrintWriter;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.Iterator;import java.util.Map;import java.util.logging.Level;import java.util.logging.Logger;/** * Represents a single pooled connection.  For the most part, it just * passes the requests to the underlying JDBC connection. * * <p>Closing the connection will return the real connection to the pool * and close any statements. */public class ManagedConnectionImpl  implements ManagedConnection, javax.sql.ConnectionEventListener {  protected static final Logger log = Log.open(ManagedConnectionImpl.class);  protected static L10N L = new L10N(ManagedConnectionImpl.class);  // Identifier for spy, etc.  private final String _id;  private final ManagedFactoryImpl _factory;  private final DBPoolImpl _dbPool;    private final DriverConfig _driver;  private final ConnectionConfig _connConfig;  private final Credential _credentials;  private PooledConnection _pooledConnection;  private Connection _driverConnection;  private XAResource _xaResource;  private LocalTransaction _localTransaction;  private ConnectionEventListener _listener;  private ConnectionEvent _connClosedEvent;  private ResourceException _connException;  private long _lastEventTime;  // Cached prepared statements.  private LruCache<PreparedStatementKey,PreparedStatementCacheItem>    _preparedStatementCache;  // Static prepared statement key.  private PreparedStatementKey _key;  // Current value for isolation  private int _isolation = -1;  // Value for getAutoCommit  private boolean _autoCommit = true;  // old value for getReadOnly  private boolean _readOnly = false;  private boolean _hasCatalog;  // old value for getCatalog  private String _catalogOrig = null;  // current value for getCatalog  private String _catalog = null;    // old value for isolation  private int _oldIsolation = -1;  // old value for getTypeMap  private Map _typeMap;  ManagedConnectionImpl(ManagedFactoryImpl factory,			DriverConfig driver,			ConnectionConfig connConfig,			Credential credentials)    throws SQLException  {    _factory = factory;    _dbPool = factory.getDBPool();    _id = _dbPool.newSpyId();          _driver = driver;    _connConfig = connConfig;    _credentials = credentials;    _connClosedEvent = new ConnectionEvent(this,					   ConnectionEvent.CONNECTION_CLOSED);    initDriverConnection();    _lastEventTime = Alarm.getCurrentTime();    int preparedStatementCacheSize = _dbPool.getPreparedStatementCacheSize();    if (preparedStatementCacheSize > 0) {      _preparedStatementCache = new LruCache<PreparedStatementKey,PreparedStatementCacheItem>(preparedStatementCacheSize);      _key = new PreparedStatementKey();    }  }  /**   * Returns the db pool.   */  DBPoolImpl getDBPool()  {    return _dbPool;  }  /**   * Returns the credentials.   */  Credential getCredentials()  {    return _credentials;  }  /**   * Returns true if statements should be wrapped.   */  boolean isWrapStatements()  {    return _dbPool.isWrapStatements();  }  /**   * Returns the underlying connection.   */  public Object getConnection(Subject subject,			      ConnectionRequestInfo info)    throws ResourceException  {    if (_connException != null)      throw _connException;    if (! ping())      return null;        _lastEventTime = Alarm.getCurrentTime();    return new UserConnection(this);  }  /**   * Associates the associate connection.   */  public void associateConnection(Object connection)    throws ResourceException  {    _lastEventTime = Alarm.getCurrentTime();    UserConnection uConn = (UserConnection) connection;    uConn.associate(this);  }  /**   * Adds a connection event listener.   */  public void addConnectionEventListener(ConnectionEventListener listener)  {    if (_listener != null && _listener != listener)      throw new IllegalStateException();    _listener = listener;  }  /**   * Removes a connection event listener.   */  public void removeConnectionEventListener(ConnectionEventListener listener)  {    if (_listener == listener)      _listener = null;  }  /**   * Returns the driver connection.   */  private void initDriverConnection()    throws SQLException  {    if (_driverConnection != null)      throw new IllegalStateException();    String user = _driver.getUser();    String password = _driver.getPassword();    if (_credentials != null) {      user = _credentials.getUserName();      password = _credentials.getPassword();    }    _pooledConnection = _driver.createPooledConnection(user, password);    if (_pooledConnection != null) {      _pooledConnection.addConnectionEventListener(this);      _driverConnection = _pooledConnection.getConnection();    }    if (_driverConnection == null)      _driverConnection = _driver.createDriverConnection(user, password);    if (_driverConnection == null)      throw new SQLException(L.l("Failed to create driver connection."));    DBPoolImpl dbPool = getDBPool();    long transactionTimeout = dbPool.getTransactionTimeout();    if (dbPool.isXA() && ! _connConfig.isReadOnly()) {      if (_pooledConnection instanceof XAConnection) {	try {	  _xaResource = ((XAConnection) _pooledConnection).getXAResource();	} catch (SQLException e) {	  log.log(Level.FINE, e.toString(), e);	}      }      if (_xaResource != null && dbPool.isXAForbidSameRM())	_xaResource = new DisjointXAResource(_xaResource);            if (transactionTimeout > 0 && _xaResource != null) {	try {	  _xaResource.setTransactionTimeout((int) (transactionTimeout / 1000));	} catch (Throwable e) {	  log.log(Level.FINER, e.toString(), e);	}      }      boolean allowLocalTransaction = true;      String className = "";      if (_pooledConnection != null)	className = _pooledConnection.getClass().getName();            if (! (_pooledConnection instanceof XAConnection)) {      }      else if (className.startsWith("oracle")) {	// Oracle does not allow local transactions	allowLocalTransaction = false;      }      else if (className.equals("com.mysql.jdbc.jdbc2.optional.MysqlXAConnection")) {	allowLocalTransaction = false;      }      if (allowLocalTransaction)	_localTransaction = new LocalTransactionImpl();    }    if (dbPool.isSpy()) {      _driverConnection = new SpyConnection(_driverConnection,					    _dbPool.getSpyDataSource(),					    _id);      if (_xaResource != null)	_xaResource = new SpyXAResource(_id, _xaResource);    }    int isolation = _connConfig.getTransactionIsolation();    if (isolation >= 0)      _driverConnection.setTransactionIsolation(isolation);    if (_connConfig.isReadOnly())      _driverConnection.setReadOnly(true);    String configCatalog = _connConfig.getCatalog();    if (configCatalog != null) {      _hasCatalog = true;      _catalogOrig = configCatalog;      _driverConnection.setCatalog(_catalogOrig);    }  }  /**   * Returns the driver connection.   */  Connection getDriverConnection()  {    return _driverConnection;  }    /*   * Returns the driver.   */  public Class getDriverClass()  {    return _driver.getDriverClass();  }    /*   * Returns the driver URL.   */  public String getURL()  {    return getDBPool().getURL();  }  /**   * Returns the XA resource for the connection.   */  public XAResource getXAResource()    throws ResourceException  {    if (_xaResource != null)      return _xaResource;    throw new NotSupportedException();  }  /**   * Returns the XA resource for the connection.   */  public LocalTransaction getLocalTransaction()    throws ResourceException  {    return _localTransaction;  }  /**   * Returns the meta data.   */  public ManagedConnectionMetaData getMetaData()    throws ResourceException  {    throw new NotSupportedException();  }  /**   * Sets the log writer.   */  public void setLogWriter(PrintWriter out)    throws ResourceException  {  }  /**   * Gets the log writer.   */  public PrintWriter getLogWriter()    throws ResourceException  {    return null;  }  /**   * Sets the isolation.   */  public void setIsolation(int isolation)    throws SQLException  {  }  /**   * Returns a new or cached prepared statement.   */  PreparedStatement prepareStatement(UserConnection uConn,				     String sql,				     int resultType)    throws SQLException  {    Connection conn = getDriverConnection();    if (conn == null)      throw new IllegalStateException(L.l("can't prepare statement from closed connection"));    if (resultType > 0)      return conn.prepareStatement(sql, resultType);    else      return conn.prepareStatement(sql);  }  /**   * Returns a new or cached prepared statement.   */  PreparedStatement prepareStatement(UserConnection uConn, String sql)    throws SQLException  {    PreparedStatementKey key = _key;    Connection conn = getDriverConnection();    if (conn == null)      throw new IllegalStateException(L.l("can't prepare statement from closed connection"));    if (key == null) {      return conn.prepareStatement(sql);    }    boolean hasItem = false;    synchronized (key) {      key.init(sql);      PreparedStatementCacheItem item = _preparedStatementCache.get(key);      if (item != null) {	UserPreparedStatement upStmt = item.toActive(uConn);	if (upStmt != null)	  return upStmt;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?