如何正确管理光滑的数据库连接?

时间:2018-10-18 19:44:44

标签: scala sqlite akka slick

AFAIK Slick访问数据库的方式是创建session的隐式实例(每个应用程序一个),然后 通过implicit参数将其传递到应用程序中的任何地方,会话将通过以下方式访问数据库 值db,我们可以使用session.db.run运行查询。

对我来说,问题是我如何知道滑动实际实例化了多少个连接(真实连接而不是概念连接)?

我之所以问这个问题,是因为我有SQLite的异常:

java.sql.SQLException: [SQLITE_BUSY]  The database file is locked (database is locked)
    at org.sqlite.DB.newSQLException(DB.java:383)
    at org.sqlite.DB.newSQLException(DB.java:387)
    at org.sqlite.DB.throwex(DB.java:374)
    at org.sqlite.NativeDB.prepare(Native Method)
    at org.sqlite.DB.prepare(DB.java:123)
    at org.sqlite.PrepStmt.<init>(PrepStmt.java:42)
    at org.sqlite.Conn.prepareStatement(Conn.java:404)
    at org.sqlite.Conn.prepareStatement(Conn.java:399)
    at org.sqlite.Conn.prepareStatement(Conn.java:383)
    at slick.jdbc.JdbcBackend$SessionDef.prepareStatement(JdbcBackend.scala:321)
    at slick.jdbc.JdbcBackend$SessionDef.prepareStatement$(JdbcBackend.scala:311)
    at slick.jdbc.JdbcBackend$BaseSession.prepareStatement(JdbcBackend.scala:433)
    at slick.jdbc.StatementInvoker.results(StatementInvoker.scala:32)
    at slick.jdbc.StatementInvoker.iteratorTo(StatementInvoker.scala:21)
    at slick.jdbc.Invoker.foreach(Invoker.scala:47)
    at slick.jdbc.Invoker.foreach$(Invoker.scala:46)
    at slick.jdbc.StatementInvoker.foreach(StatementInvoker.scala:15)
    at slick.jdbc.StreamingInvokerAction.run(StreamingInvokerAction.scala:22)
    at slick.jdbc.StreamingInvokerAction.run$(StreamingInvokerAction.scala:20)
    at slick.jdbc.SQLActionBuilder$$anon$1.run(StaticQuery.scala:95)
    at slick.jdbc.SQLActionBuilder$$anon$1.run(StaticQuery.scala:95)
    at slick.basic.BasicBackend$DatabaseDef$$anon$2.liftedTree1$1(BasicBackend.scala:242)
    at slick.basic.BasicBackend$DatabaseDef$$anon$2.run(BasicBackend.scala:242)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

那是因为SQLite不允许并发访问 如何防止Slick同时访问我的SQLite数据库?

我正在做的是以下事情:

我有一个连接到actor接收器的Akka流,该接收器使用隐式提供的会话来运行少量查询 (一个插入和四个选择)使用下面的for comprehension来说明我要解释的伪代码

val dbConnector = system.actorOf(DBConnector.props)

val sinkDBConnetor = Sink.actorRefWithAck(dbConnector, "init", "ack", "complete", println)

val sqlSink = Flow[TDM[Instant, BucketedStats[Stats.SimpleStats]]]
    .map(e => UpdateTypicalHR(e.key.get.toLong, e.when.get.from.getEpochSecond(), e.value.stats.max))
    .to(sinkDBConnetor)

class DBConnector extends Actor with ActorLogging {  
    override def receive: Receive = {
        case UpdateTypicalHR(watch_id: Long, timestamp: Long, value: Double) =>
            val request =
            (for {
                _ <- insertHr(watch_id, timestamp, value)
                t <- typicalHr(watch_id, timestamp)
                a1 <- checkDailyVariation(watch_id, timestamp)
                a2 <- check8HoursVariation(watch_id, timestamp)
                a3 <- checkHourlyVariation(watch_id, timestamp)
            } yield (t, a1 ++ a2 ++ a3)).transactionally
            session.db.run(request).onComplete {
            case Success((typical, alerts)) =>
                log.debug("Read Intic")
                sender() ! "database is free"
            case Failure(exception) =>
                session.close()
                sender() ! "database is free"
            }
    }
}

0 个答案:

没有答案