Jerry, Rémy,
On 9/3/21 07:15, Rémy Maucherat wrote:
On Fri, Sep 3, 2021 at 2:46 AM Jerry Malcolm <techst...@malcolms.com> wrote:
I have a requirement to start a new log database on the first of every
month. I still need to have access to older monthly log databases. I
do not want to create a bunch of hardcoded manually configured
individual datasources, one for each month. I have a dynamic datasource
solution that is completely implemented and working except for one
little thing.
I access the BasicDataSource implementation class for the datasource. I
have an algorithm that substitutes yyyy_MM at the appropriate spot in
the configured URL and then updates the url in the datasource. All of
this works great. I can live with the fact that the datasource can only
point to one database at a time. My concern is that once I transition
to another database, there are existing connections in the pool that are
already attached to the old database. I need to clear those out and
start over. But I don't have the luxury of bouncing tomcat to clean it up.
The apache commons BasicDataSource has a restart() method. But
unfortunately that method is omitted from the Tomcat version. There is a
close() method on the BasicDataSource. But I don't see anything that
will re-open it after closing. I thought about changing maxActive to 0,
and waiting for it to drain, then setting it back to the original
value. None of these sound like an ideal solution. Without a restart()
method, is there any other way to force all existing connections to
close and start clean?
The code is kept in sync with DBCP (with a bit of lag maybe), so these
lifecycle methods were also added to Tomcat one year ago (9.0.38+ and
8.5.58+).
We are using this at $work to bounce our database connection pools after
TLS client certificate changes. This is the code we are using to reload
the pool:
try
{
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup(getJNDIPath());
if(null == ds)
throw new ServiceException("Cannot obtain DataSource");
if(isInstanceOf(ds, "org.apache.tomcat.dbcp.dbcp2.BasicDataSource")
|| isInstanceOf(ds, "org.apache.commons.dbcp2.BasicDataSource")) {
return call(ds, "restart");
}
} catch (Exception e) {
org.apache.log4j.Logger.getLogger(this.getClass()).error("Failed
to reload DataSource " + getJNDIPath());
}
The call() method simply encapsulates all of the work to make a
reflective method call to BasicDataSource.restart().
As Rémy points out, it requires a Tomcat version 9.0.38+ or 8.5.58+.
Hope that helps,
-chris
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org