2017-11-08 19 views
2

私はdoobie(cats)を使ってscalatraアプリケーションからpostgresqlデータベースに接続しています。最近、私は、アプリケーションがすべてのトランザクションに新しい接続プールを作成していることに気付きました。私は最終的にそれを回避しました - 下を参照してください、しかしこのアプローチは'managing connections' section of the book of doobieで取られたものと全く異なっています、私は誰かがそれが賢明かどうか、または接続プールを設定する良い方法があるかどうかを確認することを望んでいました。ここで Doobieでひかり接続プールを正しく処理する方法

は、私が最初に持っていたものだ - これは動作しますが、すべての接続で新しい接続プールを作成します。

import com.zaxxer.hikari.HikariDataSource 
import doobie.hikari.hikaritransactor.HikariTransactor 
import doobie.imports._ 

val pgTransactor = HikariTransactor[IOLite](
    "org.postgresql.Driver", 
    s"jdbc:postgresql://${postgresDBHost}:${postgresDBPort}/${postgresDBName}", 
    postgresDBUser, 
    postgresDBPassword 
) 
// every query goes via this function 
def doTransaction[A](update: ConnectionIO[A]): Option[A] = { 
    val io = for { 
     xa <- pgTransactor 
     res <- update.transact(xa) ensuring xa.shutdown 
    } yield res 
    io.unsafePerformIO 
} 

私の最初の仮定の問題は、リクエストごとにensuring xa.shutdownを持つが、それはすぐに接続になり削除されたということでした残ることがなくなるまで使い切っています。

これは、問題を解決しようとする試みだったが - ensuring xa.shutdownを削除するために私を有効にし、それでも接続プールを繰り返し開閉されての結果:

val pgTransactor: HikariTransactor[IOLite] = HikariTransactor[IOLite](
    "org.postgresql.Driver", 
    s"jdbc:postgresql://${postgresDBHost}:${postgresDBPort}/${postgresDBName}", 
    postgresDBUser, 
    postgresDBPassword 
).unsafePerformIO 

def doTransaction[A](update: ConnectionIO[A]): Option[A] = { 
    val io = update.transact(pgTransactor) 
    io.unsafePerformIO 
} 

最後に、私はHikariDataSourceを作成することにより、必要な動作を得ましたオブジェクト、その後HikariTransactorコンストラクタに渡す:あなたはこのような何かを行うことができ

val dataSource = new HikariDataSource() 
dataSource.setJdbcUrl(s"jdbc:postgresql://${postgresDBHost}:${postgresDBPort}/${postgresDBName}") 
dataSource.setUsername(postgresDBUser) 
dataSource.setPassword(postgresDBPassword) 

val pgTransactor: HikariTransactor[IOLite] = HikariTransactor[IOLite](dataSource) 

def doTransaction[A](update: ConnectionIO[A], operationDescription: String): Option[A] = { 
    val io = update.transact(pgTransactor) 
    io.unsafePerformIO 
} 

答えて

1

val xa = HikariTransactor[IOLite](dataSource).unsafePerformIO 

あなたのリポジトリに渡してください。 .transactは、Slick.transactionallyのようなトランザクション境界を適用します。 例:

def interactWithDb = { 
    val q: ConnectionIO[Int] = sql"""...""" 
    q.transact(xa).unsafePerformIO 
} 
0

はい、Raduの応答が問題になります。 HikariTransactor(根底にあるHikariDataSource)は内部状態を持っていますので、それを構築することは副作用です。あなたのプログラムが始まったときにそれを一度やりたいと思って、必要に応じてそれを渡してください。ソリューションが機能するので、副作用に注意してください。

また、上記のように、私はSOを監視しません...ジッタチャネルを試してみるか質問がある場合は問題を開きます。 :-)

関連する問題