以事务方式运行并在 Future 中检索结果 [英] Run transactionally and retrieve result in Future

查看:44
本文介绍了以事务方式运行并在 Future 中检索结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How to run a transactionally statement in Slick 3.1.x, and capture the result in a Future (without the use of Await)?

这有效(但使用 Await)

This works (but uses 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)

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

However this does not print anything:

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"

This is the real code taken from the program that doesn't work. It prints "1" but it never prints "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

  }
}

推荐答案

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

Coming from the other question you asked: You are opening and then immediately closing the db connection in the finally clause. Therefore your async db operation runs against a closed db connection. That's also why it works by using Await since that blocks the execution of db.close until you received the result set.

那么如何解决这个问题?

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

Either you move db.close into future.map or better you let play-slick handle db connections for you.

附注

您应该关闭其他问题 并相应地更新此线程.

You should close your other question and update this thread accordingly instead.

这篇关于以事务方式运行并在 Future 中检索结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆