2

私の Boot.scala で、 Squerylの推奨されるトランザクション設定に従います。

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 の Web インターフェイス経由で接続でき、アプリを使用すると、データベースが適切に更新されます。ただし、JVM を再起動せずに jetty を再起動すると、次のようになります。

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 グループで同じ問題についての言及を見つけましたが、解決策はありません。

助けてくれてありがとう。

4

1 に答える 1

1

Jetty を再起動していると言うとき、実際に行っているのは Jetty 内で webapp をリロードしていると思います。h2 データベースも C3P0 も、アプリのリロード時に自動的にシャットダウンされません。これは、Lift がそれらを 2 回目に初期化しようとしたときに受け取るエラーを説明しています。最初の DB 接続が取得されるときに h2 と C3P0 の両方が初期化されるため、トランザクション ブロックを作成しない場合、エラーは表示されません。

私は BoneCP を接続プールとして使用する傾向があります。プールされた接続の最小数を > 1 に設定できます。これにより、DB_CLOSE_DELAY=-1 を必要とせずに h2 のシャットダウンが停止します。次に、次を使用できます。

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

これにより、Lift がシャットダウンされたときにすべての接続が閉じられ、h2 データベースも適切にシャットダウンされます。

于 2012-10-11T15:08:45.513 に答える