hibernate c3p0破管

我正在将hibernate 3和c3p0用于一个程序,该程序不断从某些源中提取数据并将其写入数据库。 现在问题是,由于某些原因,数据库可能变得不可用(在最简单的情况下:我只是将其关闭)。

如果要将任何内容写入数据库,则不应该有任何exception – 查询应该等待所有永恒,直到数据库再次可用。 如果我没有弄错,这是连接池可以为我做的事情之一:如果db存在问题,只需重试连接 – 在最坏的情况下为无穷大。

但相反,我得到一个破坏的管道exception,有时后面连接拒绝,然后exception传递给我自己的代码,这不应该发生。

即使我抓住exception,我怎么能再次干净地重新初始化hibernate呢? (到目前为止没有c3p0我只是简单地建立了会话工厂,但如果这可能会泄漏连接(或者可以这样做,我不会感到惊讶吗?))。

该数据库是Virtuoso开源版。

我的hibernate.xml.cfg c3p0配置:

org.hibernate.connection.C3P0ConnectionProvider false -1 30000 my_test_table 3 3 10 

顺便说一句:测试表已经创建,我得到了大量的调试输出 – 所以它似乎实际上读取了配置。

好吧,似乎BoneCP实际上实现了这一点。 它可以设置为记录事务并在网络或数据库故障时重放它:

http://jolbox.com/bonecp/downloads/site/apidocs/com/jolbox/bonecp/BoneCPConfig.html#setTransactionRecoveryEnabled(boolean)

如果我没有弄错,这是连接池可以为我做的事情之一:如果db存在问题,只需重试连接 – 在最坏的情况下为无穷大。

你错了。 连接池只是一个连接池,它包含一些已建立的数据库物理连接,用于避免在需要其中一个连接时创建这些连接的开销。

也就是说,这些连接可能会变得陈旧(例如,如果重新启动数据库)。 幸运的是,大多数连接池都可以配置为测试连接是否仍然有效,并在分发之前更新它们。 c3p0支持此function,如配置连接测试中所述 ,您实际上已经使用了各种选项之一。 因此,当数据库恢复时,应该更新您的连接。

但是,当数据库出现故障时,不要指望您的应用程序被神奇地挂起,池不会这样做。

谢谢你的回答。 我似乎还没有真正理解http://www.mchange.com/projects/c3p0/index.html#configuring_recovery一节中的最后一段

因为起初似乎c3p0可以做到这一点(检测过时的连接并重试获取所有永恒的连接而不会对应用程序代码抛出exception(当然,除非它的错误与sql语句有关而不是与连接有关),但在最后一段 – 以相当令人困惑的方式写 – 似乎c3p0无法确保100%。

所以我的解决方案是从jdbc Connection接口为我需要的方法创建一个小包装器,如果查询因连接错误而失败,它会尝试重新连接。 当然它有点hacky,因为我宁愿我的组件使用标准的Connection接口而不是我自己的接口,但至少它现在干净利落。

你忘记了:

  • 您的交易已经开始了吗?
  • 那些已经发送到数据库的预备语句呢?
  • 等等

因此,您的应用程序必须重新启动该事务。 我能想到的唯一可能的方法是让连接池跟踪对连接句柄的每次调用,并在出现错误时重放这些调用,但这会大大减慢连接池的速度。

在BoneCP( http://jolbox.com )的情况下,池通过首先捕获JDBC驱动程序抛出的exception并通过将该连接标记为有故障或通过重新创建整个连接池来处理它,从而检测到发生了故障。 。

编辑:现在正在处理。