slickでコネクションプーリングを使おうとしても、slick自体ではサポートしていない。
Connections / Transactions — Slick 2.0.0-M3 documentation
そこで、リンク先にも書いてあるように、Javaの資産であるコネクションプーリング用ライブラリが必要になる。
枯れているCommons-dbcpを試してみた。
導入方法に関しては、ググるとたくさん出てくるが、一応載せておく。
まず、DBの接続部分に関して。
複数のDBにつなげるようにメソッドを切り出している。
application.confはこんな感じ
object HogeDao with DBConnection { def findById(id: Int, db:DataSource): Option[E] = { hogeDb.withSession { implicit session => query.filter(_.id === id).firstOption } } }
こんな感じで呼び出す。
ハマったポイント
1,インスタンスの生成に注意
上のDBConnection.scalaでは、BasicDataSourceのインスタンス生成をobjectの中でやっている。
これをtraitの中で行ってはいけない。
シングルトンであるobjectの中で定義することで、BasicDataSourceを使い回し、connection poolを管理する。
しかし、traitの中で呼び出してしまうと、hogeDbがDaoなどで複数回呼ばれると、呼ばれた回数だけインスタンスが生成される。
結果、MySQL上でshow processlistを実行すると分かるように、呼ばれた回数だけコネクションが張られてしまう。
またlazy valを使い、繋がないDBに関しては、一度つなぐまでインスタンス生成を行わないようにしている
2,closeすべし
これは、scalaというより、DB自体の話。
connectionをcloseするとプールに返却されるので、closeしない限りコネクションプールの管理対象に戻らない。
Slickの非推奨のManualでコネクションを張っていると、closeし忘れが発生してしまうので、そこは要注意。
また、sessionを使いまわすとおかしなことになるので、注意。
まず、非推奨なので、使わないことをおすすめする。
所感
C3P0も試したが、同じような感じで導入できた。
HikariCPも今度試してみるかも。
ここ間違ってるってところがあれば、指摘お願いしますm(_ _)m