brettwooldridge / HikariCP

光 HikariCP・A solid, high-performance, JDBC connection pool at last.
Apache License 2.0
20.04k stars 2.94k forks source link

Connection only works once when using JDNI DataSource #1427

Open ThomasAbts opened 5 years ago

ThomasAbts commented 5 years ago

Environment

HikariCP version: 3.3.1
JDK version     : 1.8.0_191-1-ojdkbuild-b12
Database        : Oracle 12c Enterprise Edition Release 12.2.0.1.0
Tomcat 8.5.23

I have a strange problem using JDNI Datasource vs implicit use of Datasource. With JDNI everything works fine only on initial use, but when I reload the application I get "java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30008ms." I have to then restart Tomcat to get it to work again (but only once).

This is my resource (very similar to wiki example):

<Resource name="MyResourceName" auth="Container"
factory="com.zaxxer.hikari.HikariJNDIFactory"
    type="javax.sql.DataSource"
    minimumIdle="5" 
    maximumPoolSize="10"
    dataSourceClassName="oracle.jdbc.pool.OracleDataSource"
    dataSource.url="jdbc:oracle:thin:@IP:DBNAME"
    dataSource.implicitCachingEnabled="true" 
    dataSource.user="test"
    dataSource.password="test" />

This is how it is called:

hikariDataSource = new HikariDataSource();              
hikariDataSource.setDataSourceJNDI(myDatasourcePath);

It doesn't matter if I use "DriverClassName" or "DataSourceClassName". The Problem stays the same. It doesn't matter if I use HikariConfig or not.

Everything works fine, when I replace the 2 lines calling of JDNI with using setters directly (same parameters), like

hikariDataSource = new HikariDataSource();
hikariDataSource .setJdbcUrl("jdbc:oracle:thin:@IP:DBNAME); 
hikariDataSource .setUsername("test");
hikariDataSource .setPassword("test");

Using it directly I can start the application 1000 times without problems.

The same problem persits, when replacing .setDataSourceJNDI with the typical implementation like

Context contextEnv              = (Context) new InitialContext().lookup(myContext);
javax.sql.DataSource dataSource = (javax.sql.DataSource) contextEnv.lookup (myDatasourceEntry);

I am not sure if there might be a bug in Hikari, when using JDNI DataSources?

I invested 2 days debugging and researching this problem, but could not find any solution.

JoyceLikeRose commented 5 years ago

I think the datasource closed by middle-server in redeploying your project, I met similar problem,then added a wrapper on datasource, follow show you some ref code

class JndiDataSourceWrapper implement DataSource{
  private DataSource dataSources

 public JndiDataSourceWrapper (DataSource dataSource){
   t his.dataSource=dataSource;
 }
 public void close(){
    //do nothing here....
 }
}

Or you copy file from Url: https://github.com/Chris2018998/BeeCP/blob/master/src/main/java/org/jmin/bee/BeeDataSourceFactory.java