【问题标题】:Slick3 with SQLite - autocommit seems to not be working带有 SQLite 的 Slick3 - 自动提交似乎不起作用
【发布时间】:2016-07-19 12:26:40
【问题描述】:

我正在尝试使用 Slick 为 SQLite 数据库编写一些基本查询

这是我的代码:

class MigrationLog(name: String) {

    val migrationEvents = TableQuery[MigrationEventTable]

    lazy val db: Future[SQLiteDriver.backend.DatabaseDef] = {
        val db = Database.forURL(s"jdbc:sqlite:$name.db", driver = "org.sqlite.JDBC")
        val setup = DBIO.seq(migrationEvents.schema.create)

        val createFuture = for {
          tables <- db.run(MTable.getTables)
          createResult <- if (tables.length  == 0) db.run(setup) else Future.successful()
        } yield createResult

        createFuture.map(_ => db)
    }

    val addEvent: (String, String) => Future[String] = (aggregateId, eventType) => {
        val id = java.util.UUID.randomUUID().toString
        val command = DBIO.seq(migrationEvents += (id, aggregateId, None, eventType, "CREATED", System.currentTimeMillis, None))
        db.flatMap(_.run(command).map(_ => id))
    }

    val eventSubmitted: (String, String) => Future[Unit] = (id, batchId) => {
       val q = for { e <- migrationEvents if e.id === id } yield (e.batchId, e.status, e.updatedAt)
       val updateAction = q.update(Some(batchId), "SUBMITTED", Some(System.currentTimeMillis))
       db.map(_.run(updateAction))
    }

    val eventMigrationCompleted: (String, String, String) => Future[Unit] = (batchId, id, status) => {
       val q = for { e <- migrationEvents if e.batchId === batchId && e.id === id} yield (e.status, e.updatedAt)
       val updateAction = q.update(status, Some(System.currentTimeMillis))
       db.map(_.run(updateAction))
    }

    val allEvents = () => {
        db.flatMap(_.run(migrationEvents.result))
    }
}

这是我的使用方法:

val migrationLog = MigrationLog("test")
val events = for {
  id <- migrationLog.addEvent("aggregateUserId", "userAccessControl")
  _ <- migrationLog.eventSubmitted(id, "batchID_generated_from_idam")
  _ <- migrationLog.eventMigrationCompleted("batchID_generated_from_idam", id, "Successful")
  events <- migrationLog.allEvents()
} yield events

events.map(_.foreach(event => event match {
  case (id, aggregateId, batchId, eventType, status, submitted, updatedAt) => println(s"$id $aggregateId $batchId $eventType $status $submitted $updatedAt")
}))

想法是先添加事件,然后用 batchId 更新它(这也更新状态),然后在工作完成时更新状态。 events 应该包含状态为 Successful 的事件。

运行此代码后,它会打印状态为SUBMITTED 的事件。如果我等待一段时间并执行相同的allEvents 查询,或者只是使用sqlite3 从命令行检查数据库,那么它会正确更新。 在开始下一个操作之前,我正在等待解决期货,默认情况下应该启用自动提交。

我错过了什么吗?

【问题讨论】:

    标签: scala sqlite slick


    【解决方案1】:

    原来问题出在db.map(_.run(updateAction)),它返回Future[Future[Int]],这意味着在我尝试运行另一个查询时该命令尚未完成。

    db.flatMap(_.run(updateAction)) 替换它解决了这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-14
      相关资源
      最近更新 更多