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

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

Go to download

Microsoft JDBC 4.2 Driver for SQL Server. The Azure Key Vault feature in Microsoft JDBC Driver for SQL Server depends on Azure SDK for JAVA and Azure Active Directory Library For Java.

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