2

按照 Squeryl 的推荐事务设置,在我的 Boot.scala 中:

import net.liftweb.squerylrecord.SquerylRecord
import org.squeryl.Session
import org.squeryl.adapters.H2Adapter

SquerylRecord.initWithSquerylSession(Session.create(
  DriverManager.getConnection("jdbc:h2:lift_proto.db;DB_CLOSE_DELAY=-1", "sa", ""),
  new H2Adapter
))

第一次启动工作正常。我可以通过 H2 的网络界面连接,如果我使用我的应用程序,它会适当地更新数据库。但是,如果我在不重新启动 JVM 的情况下重新启动码头,我会得到:

java.sql.SQLException: No suitable driver found for jdbc:h2:lift_proto.db;DB_CLOSE_DELAY=-1

如果我将“DB_CLOSE_DELAY=-1”替换为“AUTO_SERVER=TRUE”,或者将其完全删除,也会得到相同的结果。

按照 Squeryl 列表中的建议,我尝试了 C3P0:

import com.mchange.v2.c3p0.ComboPooledDataSource

val cpds = new ComboPooledDataSource 
cpds.setDriverClass("org.h2.Driver") 
cpds.setJdbcUrl("jdbc:h2:lift_proto") 
cpds.setUser("sa") 
cpds.setPassword("")
org.squeryl.SessionFactory.concreteFactory =
  Some(() => Session.create( 
    cpds.getConnection, new H2Adapter())
  )

这会产生类似的行为:

WARNING: A C3P0Registry mbean is already registered. This probably means that an application using c3p0 was undeployed, but not all PooledDataSources were closed prior to undeployment. This may lead to resource leaks over time. Please take care to close all PooledDataSources.

为了确保不是我正在做的任何事情导致了这种情况,我在没有调用事务 {} 块的情况下启动和停止了服务器。没有抛出异常。然后我添加到我的 Boot.scala 中:

transaction { /* Do nothing */ }

并且再次抛出异常(我假设因为连接是惰性的)。所以我将 db 初始化代码从 Lift 移到了它自己的文件中:

SessionFactory.concreteFactory = Some(()=>
  Session.create(
  java.sql.DriverManager.getConnection("jdbc:h2:mem:test", "sa", ""),
  new H2Adapter
))
transaction {}

结果没有改变。我究竟做错了什么?我在 Squeryl 文档中找不到任何需要显式关闭连接或会话的内容,这是我第一次使用 JDBC。

我在 Lift google group 上发现了同样的问题,但没有解决方案。

谢谢你的帮助。

4

1 回答 1

1

当您说要重新启动 Jetty 时,我认为您实际上在做的是在 Jetty 中重新加载您的 webapp。当您的应用程序重新加载时,h2 数据库或 C3P0 都不会自动关闭,这解释了当 Lift 尝试第二次初始化它们时您收到的错误。当您不创建事务块时,您看不到错误,因为在检索第一个数据库连接时,h2 和 C3P0 都已初始化。

我自己倾向于使用 BoneCP 作为连接池。您可以将池连接的最小数量配置为 > 1,这将阻止 h2 关闭而无需 DB_CLOSE_DELAY=-1。然后你可以使用:

    LiftRules.unloadHooks append { () =>
      yourPool.close() //should destroy the pool and it's associated threads
    }

这将在 Lift 关闭时关闭所有连接,这也应该正确关闭 h2 数据库。

于 2012-10-11T15:08:45.513 回答