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

com.atomikos.datasource.pool.ConnectionPoolWithConcurrentValidation Maven / Gradle / Ivy

/**
 * Copyright (C) 2000-2020 Atomikos 
 *
 * LICENSE CONDITIONS
 *
 * See http://www.atomikos.com/Main/WhichLicenseApplies for details.
 */

package com.atomikos.datasource.pool;

import java.util.Iterator;

import com.atomikos.logging.Logger;
import com.atomikos.logging.LoggerFactory;


public class ConnectionPoolWithConcurrentValidation extends ConnectionPool
{
	private static final Logger LOGGER = LoggerFactory.createLogger(ConnectionPoolWithConcurrentValidation.class);

	public ConnectionPoolWithConcurrentValidation ( ConnectionFactory connectionFactory , ConnectionPoolProperties properties ) throws ConnectionPoolException
	{
		super(connectionFactory, properties);
	}
	
	@Override
	protected ConnectionType recycleConnectionIfPossible() throws Exception {
		ConnectionType ret = null;
		XPooledConnection xpc = findFirstRecyclablePooledConnectionForCallingThread();
		if (xpc != null) {
			ret = concurrentlyTryToRecycle(xpc);
		}
		return ret;
	}

	@Override
	protected ConnectionType retrieveFirstAvailableConnection() {
		ConnectionType ret = null;
		XPooledConnection xpc = claimFirstAvailablePooledConnection();
		if (xpc != null) {
			ret = concurrentlyTryToUse(xpc);
		}
		return ret;
	}
	
	private ConnectionType concurrentlyTryToRecycle(XPooledConnection xpc) throws Exception {
		ConnectionType ret = null;
		synchronized(xpc) { // just to be sure, although concurrent threads should not happen
			if (xpc.canBeRecycledForCallingThread()) { 
				ret = xpc.createConnectionProxy();
			}
		}
		return ret;
	}
	
	private ConnectionType concurrentlyTryToUse(XPooledConnection xpc) {
		ConnectionType ret = null;
			try {
				ret = xpc.createConnectionProxy();
				// here, connection is no longer available for other threads
			} catch ( CreateConnectionException ex ) {
				String msg = this +  ": error creating proxy of connection " + xpc;
				LOGGER.logDebug( msg , ex);
				removePooledConnection(xpc);
			} finally {
				logCurrentPoolSize();
			}
		return ret;
	}

	private synchronized XPooledConnection claimFirstAvailablePooledConnection() {
		XPooledConnection ret = null;
		Iterator> it = connections.iterator();			
		while ( it.hasNext() && ret == null ) {
			XPooledConnection xpc =  it.next();
			if (xpc.markAsBeingAcquiredIfAvailable()) {
				ret = xpc;
			}
		}
		return ret;
	}
	
	private synchronized XPooledConnection findFirstRecyclablePooledConnectionForCallingThread() {
		XPooledConnection ret = null;
		Iterator> it = connections.iterator();			
		while ( it.hasNext() && ret == null ) {
			XPooledConnection xpc =  it.next();
			if (xpc.canBeRecycledForCallingThread()) {
				ret = xpc;
			}
		}
		return ret;
	}
	
	private synchronized void removePooledConnection(XPooledConnection xpc) {
		connections.remove(xpc);
		destroyPooledConnection(xpc, false);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy