* @param tran Transaction
* @return ResourceHandle resource associated with the thread, if any
*/
protected ResourceHandle prefetch(ResourceSpec spec,
ResourceAllocator alloc, Transaction tran) {
AssocWithThreadResourceHandle ar = localResource.get();
if (ar != null) {
//synch on ar and do a quick-n-dirty check to see if the local
//resource is usable at all
synchronized (ar.lock) {
if ((ar.getThreadId() != Thread.currentThread().getId()) ||
ar.hasConnectionErrorOccurred() ||
ar.isDirty() || !ar.isAssociated()) {
//we were associated with someone else or resource error
//occurred or resource was disassociated and used by some one else. So evict
//NOTE: We do not setAssociated to false here since someone
//else has associated this resource to themself. Also, if
//the eviction is because of a resourceError, the resource is
//not going to be used anyway.
localResource.remove();
return null;
}
if (ar.getResourceState().isFree() &&
ar.getResourceState().isUnenlisted()) {
if (matchConnections) {
if (!alloc.matchConnection(ar)) {
//again, since the credentials of the caller don't match
//evict from ThreadLocal
//also, mark the resource as unassociated and make this resource
//potentially usable
localResource.remove();
ar.setAssociated(false);
if(poolLifeCycleListener != null){
poolLifeCycleListener.connectionNotMatched();
}
return null;
}
if(poolLifeCycleListener != null){
poolLifeCycleListener.connectionMatched();
}
}
if (!isConnectionValid(ar, alloc)) {
localResource.remove();
ar.setAssociated(false);
// disassociating the connection from the thread.
// validation failure will mark the connectionErrorOccurred flag
// and the connection will be removed whenever it is retrieved again
// from the pool.
return null;
}
setResourceStateToBusy(ar);
if (maxConnectionUsage_ > 0) {
ar.incrementUsageCount();
}
if(poolLifeCycleListener != null) {
poolLifeCycleListener.connectionUsed(ar.getId());
//Decrement numConnFree
poolLifeCycleListener.decrementNumConnFree();
}
return ar;