【问题标题】:Cleaning up connection pool before Java process exit在 Java 进程退出之前清理连接池
【发布时间】:2013-09-14 17:29:33
【问题描述】:

我有一个 java 应用程序,每隔几分钟就会从脚本中调用一次。流程是:

  1. 脚本每隔几分钟调用一次 java 进程。
  2. java 程序运行几分钟(有时更短),进行一些处理,完成后通过调用 System.exit(0) 退出。
  3. 在第 2 步中,为了进行处理,我们使用c3p0 连接池连接到 MySQL DB。

每次我们从池中获得连接时,我们都会调用close()。我们还将unreturnedConnectionTimeout 设置为20,以便任何时候连接的帮助时间过长或未关闭,c3p0 都会处理它。

我的问题是,一旦步骤 2 中的所有处理完成,在我们通过调用System.exit(0) 退出之前,我们是否需要清理连接池?

我知道使用连接池调用close() 只会将连接返回到池中,而实际上并没有“关闭”连接。那么在退出之前我需要对 conn 池进行任何清理吗?如果我不进行任何清理并退出 JVM,与 DB 的连接是否仍然存在,或者 c3p0 是否清理/强制关闭它们?谢谢!

【问题讨论】:

  • 连接无论如何都不能在JVM进程中存活。当进程退出时,操作系统将关闭所有打开的套接字,除非你运行的是像 NetWare 3 或 4 这样的奇怪东西。

标签: java mysql jdbc connection-pooling c3p0


【解决方案1】:

如果你使用com.mchange.v2.c3p0.PooledDataSource的实例(例如com.mchange.v2.c3p0.ComboPooledDataSource),你可以使用com.mchange.v2.c3p0.DataSources.destroy()的方法。

这个方法:

立即释放 C3P0 数据源持有的资源(线程和数据库连接)。

只有由 poolingDataSource() 方法创建的 DataSource 才拥有任何非内存资源。在非池化的数据源上调用此方法实际上是无操作的。

您可以放心地假定,销毁一个封装在该库创建的另一个 DataSource 周围的池化 DataSource 会同时破坏外部和封装的 DataSource。没有理由为了显式销毁它而持有对嵌套 DataSource 的引用。

PooledDataSource dataSource = new ComboPooledDataSource();
// everything you do

DataSources.destroy(dataSource);
System.exit(0);

换一种方式,(同样,如果您使用com.mchange.v2.c3p0.PooledDataSource 的实例),方法com.mchange.v2.c3p0.PooledDataSource.html#hardReset()

立即销毁与此数据源关联的所有池化和签出连接。 PooledDataSource 在第一次获取连接之前重置为其初始状态,还没有任何池处于活动状态,但已为请求做好准备。

PooledDataSource dataSource = new ComboPooledDataSource();
// everything you do

dataSource.hardReset();

System.exit(0);

dataSource.close() 方法是最好的选择,因为它更明显。始终建议关闭资源。连接可能会在数据库中保持打开一段时间,但在超时后会关闭。此行为取决于数据库供应商。

【讨论】:

  • 谢谢保罗!我看到了那个方法。问题是我需要调用破坏吗?如果我不调用destroy(),jvm 退出时c3p0 池中的连接会发生什么情况? MySQL 服务器是否也会断开连接或保留它们?还有哪个更好:PooledDataSource.close() 或 DataSources.destroy()?
  • 您只需要dataSource.close(),因为它更简单。方法hardReset()对维护很有用。
猜你喜欢
  • 1970-01-01
  • 2016-05-29
  • 2011-12-16
  • 2012-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多