Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions modules/jdbc-pool/build.properties.default
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@ tomcat.dbcp.jar=${tomcat.home}/lib/tomcat-dbcp.jar
tomcat.juli.jar=${tomcat.home}/bin/tomcat-juli.jar
tomcat.loc=https://archive.apache.org/dist/tomcat/tomcat-8/v${tomcat.version}/bin/apache-tomcat-${tomcat.version}.zip

tomcat.project.loc=https://svn.apache.org/repos/asf/tomcat/trunk/webapps/docs/project.xml
tomcat.project.loc=https://github.com/apache/tomcat/tree/main/webapps/docs/project.xml
tomcat.project.dest=${base.path}/project.xml

tomcat.xsl.loc=https://svn.apache.org/repos/asf/tomcat/trunk/webapps/docs/tomcat-docs.xsl
tomcat.xsl.loc=https://github.com/apache/tomcat/tree/main/webapps/docs/tomcat-docs.xsl
tomcat.xsl.dest=${base.path}/tomcat-docs.xsl

derby.home=${base.path}/db-derby-10.5.1.1-bin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collections;
Expand Down Expand Up @@ -138,6 +140,13 @@ public class ConnectionPool {
private final AtomicLong removeAbandonedCount = new AtomicLong(0);
private final AtomicLong releasedIdleCount = new AtomicLong(0);

/**
* Request boundaries
*/
private volatile boolean requestBoundaryMethodsInitialised = false;
private Method beginRequest = null;
private Method endRequest = null;

//===============================================================================
// PUBLIC METHODS
//===============================================================================
Expand Down Expand Up @@ -343,6 +352,14 @@ protected Connection setupConnection(PooledConnection con) throws SQLException {
} else {
connection = (Connection)proxyClassConstructor.newInstance(new Object[] {handler});
}
Connection underlyingConnection = con.getConnection();
if (hasRequestBoundaryMethods(underlyingConnection)) {
try {
beginRequest.invoke(underlyingConnection);
} catch (InvocationTargetException | IllegalAccessException ex) {
log.warn("Error calling beginRequest on connection", ex);
}
}
//return the connection
return connection;
}catch (Exception x) {
Expand Down Expand Up @@ -812,6 +829,28 @@ protected PooledConnection createConnection(long now, PooledConnection notUsed,
}//catch
}

/**
* If request boundaries are not initialised, checks if beginRequest and
* endRequest methods are implemented on connection object.
*
* @param connection The connection
* @return Returns true if connection is not null and connection implements
* JDBC 4.3 beginRequest and endRequest methods
*/
private boolean hasRequestBoundaryMethods(Connection connection) {
if (!requestBoundaryMethodsInitialised && connection != null) {
try {
beginRequest = connection.getClass().getMethod("beginRequest");
endRequest = connection.getClass().getMethod("endRequest");
} catch (NoSuchMethodException ex) {
// begin and end request not implemented, ignore exception
} finally {
requestBoundaryMethodsInitialised = true;
}
}
return (connection != null && beginRequest != null && endRequest != null);
}

/**
* Validates and configures a previously idle connection
* @param now - timestamp
Expand Down Expand Up @@ -1027,6 +1066,14 @@ protected void returnConnection(PooledConnection con) {
con.clearWarnings();
con.setStackTrace(null);
con.setTimestamp(System.currentTimeMillis());
Connection underlyingConnection = con.getConnection();
if (hasRequestBoundaryMethods(underlyingConnection)) {
try {
endRequest.invoke(underlyingConnection);
} catch (InvocationTargetException | IllegalAccessException ex) {
log.warn("Error calling endRequest on connection", ex);
}
}
if (((idle.size()>=poolProperties.getMaxIdle()) && !poolProperties.isPoolSweeperEnabled()) || (!idle.offer(con))) {
if (log.isDebugEnabled()) {
log.debug("Connection ["+con+"] will be closed and not returned to the pool, idle["+idle.size()+"]>=maxIdle["+poolProperties.getMaxIdle()+"] idle.offer failed.");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.tomcat.jdbc.test;

import org.apache.tomcat.jdbc.test.driver.Driver;

import java.sql.Connection;

import org.junit.Test;
import org.junit.Assert;

public class ConnectionBoundariesTest extends DefaultTestCase {


@Override
public org.apache.tomcat.jdbc.pool.DataSource createDefaultDataSource() {
// TODO Auto-generated method stub
org.apache.tomcat.jdbc.pool.DataSource ds = super.createDefaultDataSource();
ds.getPoolProperties().setDriverClassName(Driver.class.getName());
ds.getPoolProperties().setUrl(Driver.url);
ds.getPoolProperties().setInitialSize(0);
ds.getPoolProperties().setMaxIdle(10);
ds.getPoolProperties().setMinIdle(10);
ds.getPoolProperties().setMaxActive(10);
return ds;
}
@Test
public void connectionWithRequestBoundariesTest() throws Exception {
datasource.getPoolProperties().getDbProperties().setProperty("requestBoundaries", "true");
Connection connection = datasource.getConnection();
Assert.assertEquals("Connection.beginRequest() count", 1, Driver.beginRequestCount.get());
Assert.assertEquals("Connection.endRequest() count", 0, Driver.endRequestCount.get());
connection.close();
Assert.assertEquals("Connection.beginRequest() count", 1, Driver.beginRequestCount.get());
Assert.assertEquals("Connection.endRequest() count", 1, Driver.endRequestCount.get());
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,12 @@ public int getNetworkTimeout() throws SQLException {
return 0;
}

public void beginRequest() {
Driver.beginRequestCount.incrementAndGet();
}

public void endRequest() {
Driver.endRequestCount.incrementAndGet();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ public class Driver implements java.sql.Driver {
public static final AtomicInteger connectCount = new AtomicInteger(0);
public static final AtomicInteger disconnectCount = new AtomicInteger(0);

public static final AtomicInteger beginRequestCount = new AtomicInteger(0);
public static final AtomicInteger endRequestCount = new AtomicInteger(0);

public static void reset() {
connectCount.set(0);
disconnectCount.set(0);
Expand Down