com.microsoft.sqlserver.jdbc.SQLServerPooledConnection Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mssql-jdbc Show documentation
Show all versions of mssql-jdbc Show documentation
Microsoft JDBC Driver for SQL Server.
//---------------------------------------------------------------------------------------------------------------------------------
// File: SQLServerPooledConnection.java
//
//
// Microsoft JDBC Driver for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//---------------------------------------------------------------------------------------------------------------------------------
package com.microsoft.sqlserver.jdbc;
import javax.sql.*;
import java.sql.*;
import java.util.*;
import java.util.logging.*;
/**
* SQLServerPooledConnection represents a database physical connection in a connection pool. If provides
* methods for the connection pool manager to manage the connection pool. Applications typically
* do not instantiate these connections directly.
*/
public class SQLServerPooledConnection implements PooledConnection {
private final Vector listeners;
private SQLServerDataSource factoryDataSource;
private SQLServerConnection physicalConnection;
private SQLServerConnectionPoolProxy lastProxyConnection;
private String factoryUser, factoryPassword;
private java.util.logging.Logger pcLogger;
static private int basePooledConnectionID = 0; // Unique id generator for each PooledConnection instance (used for logging).
private final String traceID;
SQLServerPooledConnection(SQLServerDataSource ds, String user, String password) throws SQLException
{
listeners = new Vector();
// Piggyback SQLServerDataSource logger for now.
pcLogger = SQLServerDataSource.dsLogger;
// Create the physical connection.
factoryDataSource = ds;
factoryUser = user;
factoryPassword = password;
if (pcLogger.isLoggable(Level.FINER))
pcLogger.finer(toString()+ " Start create new connection for pool.");
physicalConnection = createNewConnection();
String nameL = getClass().getName();
traceID = nameL.substring(1 + nameL.lastIndexOf('.')) + ":" +nextPooledConnectionID();
if (pcLogger.isLoggable(Level.FINE))
pcLogger.fine(toString() + " created by (" + ds.toString() +")" +" Physical connection " + safeCID() + ", End create new connection for pool");
}
/**
* This is a helper function to provide an ID string suitable for tracing.
*/
public String toString()
{
return traceID;
}
// Helper function to create a new connection for the pool.
private SQLServerConnection createNewConnection() throws SQLException
{
return factoryDataSource.getConnectionInternal(factoryUser, factoryPassword, this);
}
/**
* Creates an object handle for the physical connection that this PooledConnection object represents.
* @throws SQLException
*/
public Connection getConnection() throws SQLException {
if (pcLogger.isLoggable(Level.FINER))
pcLogger.finer(toString() + " user:(default).");
synchronized(this)
{
// If physical connection is closed, throw exception per spec, this PooledConnection is dead.
if (physicalConnection == null)
{
SQLServerException.makeFromDriverError(null, this,
SQLServerException.getErrString("R_physicalConnectionIsClosed"),
"", true);
}
// Check with security manager to insure caller has rights to connect.
// This will throw a SecurityException if the caller does not have proper rights.
physicalConnection.doSecurityCheck();
if (pcLogger.isLoggable(Level.FINE))
pcLogger.fine(toString() + " Physical connection, " + safeCID());
if(null != physicalConnection.getAuthenticationResult()){
if(Util.checkIfNeedNewAccessToken(physicalConnection))
{
physicalConnection = createNewConnection();
}
}
// The last proxy connection handle returned will be invalidated (moved to closed state)
// when getConnection is called.
if(null != lastProxyConnection )
{
// if there was a last proxy connection send reset
physicalConnection.resetPooledConnection();
if (pcLogger.isLoggable(Level.FINE)&& !lastProxyConnection.isClosed())
pcLogger.fine(toString() + "proxy " + lastProxyConnection.toString()+ " is not closed before getting the connection.");
// use internal close so there wont be an event due to us closing the connection, if not closed already.
lastProxyConnection.internalClose();
}
lastProxyConnection = new SQLServerConnectionPoolProxy(physicalConnection);
if (pcLogger.isLoggable(Level.FINE)&& !lastProxyConnection.isClosed())
pcLogger.fine(toString() + " proxy " +lastProxyConnection.toString()+ " is returned.");
return lastProxyConnection;
}
}
// Notify any interested parties (e.g. pooling managers) of a ConnectionEvent activity
// on the connection. Calling notifyEvent with null event will place the
// connection back in the pool. Calling notifyEvent with a non-null event is
// used to notify the pooling manager that the connection is bad and should be removed
// from the pool.
void notifyEvent(SQLServerException e)
{
if (pcLogger.isLoggable(Level.FINER))
pcLogger.finer(toString() + " Exception:" + e + safeCID());
// close the proxy on fatal error event. Note exception is null then the event comes from the proxy close.
if(null != e)
{
synchronized(this)
{
if( null != lastProxyConnection)
{
lastProxyConnection.internalClose();
lastProxyConnection = null;
}
}
}
// A connection handle issued from this pooled connection is closing or an error occurred in the connection
synchronized(listeners)
{
for (int i=0; i