运行 交易并在 Future 中检索结果

Run transactionally and retrieve result in Future

如何在 Slick 3.1.x 中 运行 一个 transactionally 语句,并在 Future 中捕获结果(不使用 Await)?

这有效(但使用 Await)

 val action = db.run((for {
      _ <- table1.filter(_.id1 === id).delete
      _ <- table2.filter(_.id2=== id).delete
    } yield ()).transactionally)
    val result = Await.result(action, Duration.Inf)

但是这不会打印任何内容:

val future = db.run((for {
      _ <- table1.filter(_.id1 === id).delete
      _ <- table2.filter(_.id2=== id).delete
    } yield ()).transactionally)
 future.map { result => println("result:"+result) }

更新

这是从不起作用的程序中提取的真实代码。它打印“1”但从不打印“2”

case class UserRole (sk: Int, name: String)

class UserRoleDB(tag: Tag) extends Table[UserRole](tag, "user_roles") {
  def sk = column[Int]("sk", O.PrimaryKey)
  def name = column[String]("name")
  def * = (sk, name) <>  ((UserRole.apply _).tupled, UserRole.unapply)
}

class Test extends Controller  {

  def index = Action.async { request =>

    val db = Database.forConfig("db1")
    val userRoles = TableQuery[UserRoleDB]
    val ur = UserRole(1002,"aaa")

    try {

          val action = (for {
                  userRole2 <- userRoles += ur
              } yield (userRole2)).transactionally

          val future = db.run(action)
          println(1)
//        val result = Await.result(future, Duration.Inf)
          future.map { result => {
             println(2)
             Ok("Finished OK")
           }
          }
      } 
      finally db.close

  }
}

你的第二个例子很好。我的猜测是你要么 运行 它在独立程序中要么在测试中 - 它只是在 future 有机会被执行之前完成。

尝试在第二个示例中的代码之后添加一些睡眠,您会看到它正在打印。这绝对不是你在实际代码中会做的事情(这个睡眠),但它会告诉你它应该正常工作。

来自 :您正在打开然后立即关闭 finally 子句中的数据库连接。因此,您的异步数据库操作针对关闭的数据库连接运行。这也是它通过使用 Await 工作的原因,因为它会阻止 db.close 的执行,直到您收到结果集。

那么如何解决这个问题?

要么将 db.close 移动到 future.map,要么让 play-slick 为您处理数据库连接。

旁注

您应该关闭 并相应地更新此线程。