2017-11-08 9 views
2

Ich benutze Doobie (Katzen), um eine Verbindung zu einer Postgresql-Datenbank von einer Scalatra-Anwendung herzustellen. Kürzlich ist mir aufgefallen, dass die App für jede Transaktion einen neuen Verbindungspool erstellt hat. Ich habe schließlich daran gearbeitet - siehe unten, aber dieser Ansatz ist ganz anders als in der 'managing connections' section of the book of doobie, ich hoffte, jemand könnte bestätigen, ob es sinnvoll ist oder ob es eine bessere Möglichkeit gibt, den Verbindungspool einzurichten.Wie man den Hikari-Verbindungspool mit Doobie richtig behandelt

Hier ist, was ich hatte zunächst - das funktioniert aber eine neue Verbindung Pool an jedem Anschluss:

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 
} 

Mein erstes war davon aus, dass das Problem ensuring xa.shutdown auf jeder Anfrage wurde mit, aber es führt zu Verbindungen zu entfernen schnell bis es keine mehr gibt.

Dies war ein Versuch, das Problem zu beheben - ermöglichte es mir ensuring xa.shutdown zu entfernen, führte aber nach wie vor in dem Verbindungspool wiederholt geöffnet und geschlossen werden:

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 
} 

Schließlich bekam ich das gewünschte Verhalten durch einen HikariDataSource Schaffung Objekt und dann in den HikariTransactor Konstruktor:

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 
} 

Antwort

1

Sie können etwas tun:

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

und übergeben Sie es an Ihre Repositories. wendet die Transaktionsgrenzen an, wie Slick.transactionally. Z. B .:

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

Ja, die Antwort von Radu das Problem bekommt. Die HikariTransactor (die zugrunde liegende HikariDataSource wirklich) hat internen Zustand, so dass es ein Nebeneffekt ist; und Sie möchten es einmal machen, wenn Ihr Programm startet und es nach Bedarf weitergeben. So funktioniert Ihre Lösung, beachten Sie nur den Nebeneffekt.

Auch, wie bereits erwähnt, ich nicht SO überwachen ... versuchen Sie den Gitter-Kanal oder ein Problem zu öffnen, wenn Sie Fragen haben. :-)

Verwandte Themen