All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.microsoft.sqlserver.jdbc.SQLServerPooledConnection Maven / Gradle / Ivy

There is a newer version: 12.8.1.jre11
Show newest version
//---------------------------------------------------------------------------------------------------------------------------------
// 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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy