Jenkins 在部署 SpringMVC JPA webapp MySQL 连接未释放 HikariCP

Jenkins at deploy of a SpringMVC JPA webapp MySQL connections not freed HikariCP

环境: Ubuntu 14.04.4

开发中的应用详情: Spring 4.2.5.RELEASE MVC webapp, MySQL with 151 + 1 MAX_CONNECTIONS, Hibernate,HikariCP 作为数据源,每个池 20 个连接,1 个池。

自动化部署工具:Jenkins

部署容器: Tomcat 7

先决条件:
1. 应用程序已经启动并运行,可通过网络访问。

用例:
1.登录到mysql命令行并执行:show processlist;
2. 在命令行中观察 20 个连接 + 1 个你的连接。
3. 在 Jenkins 中触发新构建,并等待将新的 *.war 部署到 tomcat
4.执行:显示进程列表;在 mysql 命令行中
5. 观察 40 个连接 + 1,你在命令行中的连接。
6. 观察连接增加到 MAX_CONNECTIONS + 1,此后 Jenkins 无法构建,因为需要数据库的单元测试失败。

预期: 在访问应用程序的情况下最多 20 个连接,如果应用程序空闲则根本没有连接(这是我在本地开发 Windows 8.1 Pro 机器上观察到的行为)

HikariCP 数据源详细信息:

@Bean
public LocalContainerEntityManagerFactoryBean getEntityManagerFactoryBean() {
    LocalContainerEntityManagerFactoryBean sessionFactory = new LocalContainerEntityManagerFactoryBean();
    sessionFactory.setDataSource(dataSource());
    sessionFactory.setPackagesToScan("com.myapp");

    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    sessionFactory.setJpaVendorAdapter(vendorAdapter);
    sessionFactory.setJpaProperties(hibernateProperties());

    return sessionFactory;
}

private DataSource dataSource() {

    final HikariDataSource ds = new HikariDataSource();
    ds.setMaximumPoolSize(20);
    ds.setDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource");
    ds.addDataSourceProperty("url", "jdbc:mysql://localhost/myapp");
    ds.addDataSourceProperty("user", "usr");
    ds.addDataSourceProperty("password", "pwd");
    ds.addDataSourceProperty("cachePrepStmts", true);
    ds.addDataSourceProperty("prepStmtCacheSize", 250);
    ds.addDataSourceProperty("prepStmtCacheSqlLimit", 2048);
    ds.addDataSourceProperty("useServerPrepStmts", true);

    return ds;
}

private Properties hibernateProperties() {
    final Properties properties = new Properties();
    properties.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
    properties.put("hibernate.hbm2ddl.auto", "validate");
    properties.put("hibernate.implicit_naming_strategy", "legacy-jpa");
    return properties;
}

似乎连接没有释放,即使在重新部署应用程序之后也是如此。有什么想法吗?

最后做了以下事情:

public class MyLocalContainerEntityManagerFactoryBean extends LocalContainerEntityManagerFactoryBean {

public static final LoggerWrapper logger = new LoggerWrapper(MyLocalContainerEntityManagerFactoryBean.class);

@Override
public void destroy() {

    logger.warning("Destroying MyLocalContainerEntityManagerFactoryBean!");

    DataSource ds = getDataSource();
    if(ds instanceof HikariDataSource) {
        HikariDataSource hds = (HikariDataSource)ds;

        logger.warning("Closing the Hikari data source!");
        hds.close();
    }

    super.destroy();
}

}

现在一切都按预期进行,即使经过几次 deploy/re-deploy 操作!