2

我正在使用Hibernatewithc3p0进行连接池。由于我在多分片数据库环境中工作,并且分片停机的可能性是一个现实的用例场景(通过手头应用程序外部的方式,例如有人出于任何原因将分片关闭),我正在尝试使用 c3p0一旦检测到数据库连接断开,就显式关闭 Hibernate 会话,以便我可以在多分片扫描中跳过特定分片的会话。

有没有办法配置 c3p0 来通知 Hibernate,Session.close()一旦发现连接断开就调用它,以便调用Session.isOpen()可以返回一个有意义的布尔值?

相关: 先发制人且优雅地检查 org.hibernate.Session 是否仍处于连接状态(通过 c3p0)

4

1 回答 1

3

简短的回答是否定的,c3p0 在这里帮不了你。

听起来(看这里和你之前的问题)你正在做一些与 c3p0 交叉目的的事情,也就是说你正在持有长期存在的会话,而不是根据需要创建会话然后立即销毁它们。那种东西是很脆弱的。这是为了避免存在连接池的架构。

IMO,您最好的选择是“不要那样做”。永远不要缓存会话。然后普通的连接测试(可能也设置了 checkoutTimeout)将解决问题。如果分片关闭,尝试获取连接将失败,如果这是最好的解决方法,您可以跳过分片。

c3p0 对休眠一无所知。c3p0 的作者感谢 hibernate 普及了他的(我的)库,但是 c3p0 不知道 Session 是什么,只是一个 Connection。理论上,c3p0 可以帮助您的唯一方法是,它可以在发现数据库已关闭时向您报告一个事件(根据您的配置,这可能会非常迅速或非常缓慢)。您可以通过 close()ing 会话来响应事件。

不幸的是,c3p0(还)没有提供用户可以用来响应采集失败的钩子。可能——这是我正在考虑为 0.9.6 添加的功能。但现在没有。但是,实现一些可以轮询您的分片并自己关闭它们的会话的东西将是非常微不足道的。所有 c3p0 要注意中断都会调用 DriverManager.getConnection( ... ) 或 dataSource.getConnection() 并观察异常。你可以自己做!

不过,我仍然强烈推荐第一个解决方案。摆脱长期存在的 Session 对象。

于 2013-10-30T02:11:54.627 回答