我有一个应用程序,我们将其称为 App.class
,它每秒检查数据库中的实时事件。
我遇到了一个数据库关闭的实例,App.class
不断重试并抛出异常。
我想要实现的是实时判断是否有有效连接。
我可以通过以下方式获取提供商:
C3P0ConnectionProvider 提供程序 = (C3P0ConnectionProvider) sessionFactoryImpl.getConnectionProvider()
我可以通过执行以下操作来检查连接是否已关闭:provider.getConnection().isClosed()
。
但是,如果数据库已关闭并且我尝试调用 provider.getConnection()
,App.class
会挂起一段时间(可能是在尝试寻找连接) ),然后抛出异常。
我想知道是否有一种简单的方法来确定连接是否存在,而不是仅仅在发生错误/异常时捕获它。
最佳答案
因此,c3p0 无法告诉您数据库是否“关闭”。从形而上学、认识论的角度来看,它只是无法获得这些信息。它仅观察网络墙上 DBMS 的影子。
c3p0 可以为您做一些事情:
- 它可以在将连接提供给您之前对其进行测试
- 它不会让你悬而未决
- 您可以提前询问它是否有可能有可用的连接,而无需等待。
听起来您已经要求 c3p0 在结帐时通过 hibernate.c3p0.validate
或 c3p0.testConnectionOnCheckout
为您测试连接。如果没有,当数据库关闭时,您不会看到您的应用程序卡在 getConnection() 上,而当您尝试使用连接时,您只会看到失败。 (您可能会在 checkin 和空闲时测试连接。下面详细介绍了这种可能性。)
您可以设置配置参数c3p0.checkoutTimeout,而不是忍受挂起。 ,这样,如果 c3p0 没有良好的连接来相对快速地为您提供服务,它就会通过异常让您自由。
理想情况下,您可能更愿意在尝试检查连接并短暂挂起之前提前知道是否有良好的连接可用。您可以通过 c3p0 的 PooledDataSource 上的方法询问 c3p0 连接是否可能立即可用。界面。如果您有权访问 PooledDataSource pds
,您只需执行类似的操作
int idle = pds.getNumIdleConnectionsDefaultUser();
并且可以知道如果至少有一些空闲连接,对 getConnection()
的调用是否可能很快成功。 (你不能保证,因为 c3p0 和 hibernate 是非常异步的,所以在你的检查和结账尝试之间,事情可能会发生变化。不,你不能尝试使用 synchronized
block 或者使这些事情成为原子的东西,c3p0 的池在内部进行锁定,而不是在外部 DataSource
级别。)
但是,即使有空闲连接,在测试它们之前您也不会知道它们是否良好,如果 DBMS 关闭,您将挂起,因为 c3p0 会尝试所有空闲连接,拒绝它们,然后徒劳地等待尝试获取连接。您希望 c3p0 预先测试连接,这样,如果没有一个连接良好,则没有一个连接显示为空闲。
您无法完美地做到这一点,但您可以通过将结帐时的连接测试替换为检查时的连接测试并结合空闲连接的频繁测试来接近这一点。请参阅c3p0's docs了解如何操作的详细信息。如果这样做,坏连接将很快从池中逐出,并且空闲连接计数将接近空闲好连接的计数。因此,您将有一定的信心(尽管不完美),如果您看到空闲连接,则 DBMS 已启动,并且对 getConnection()
的调用将很快成功。当 DBMS 刚刚崩溃但 c3p0 尚未检测到它时,使用 checkoutTimeout
进行备份,您将非常接近您想要的位置。
哦,要从 hibernate 连接提供程序获取 PooledDataSource,looking at the source code ,应该是这样的...
import com.mchange.v2.c3p0.PooledDataSource;
PooledDataSource pds = provider.unwrap(PooledDataSource.class);
int idle = pds.getNumIdleConnectionsDefaultUser();
我还没有尝试过这段代码,而且我是在匆忙中写的(抱歉!),但是如果值得这么麻烦的话,那应该可行。我认为大多数用户只是使用 c3p0.checkoutTimeout 来限制数据库中断的时间成本,而不需要麻烦地获取 PooledDataSource 来询问空闲连接。但如果你需要的话,你可以得到它。
关于java - hibernate/C3P0 : Is there a way to check if the connection is down in real time?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37334807/