以事务方式运行并在Future中检索结果

时间:2016-12-01 04:22:12

标签: scala slick slick-3.0

如何在Slick 3.1.x中运行 val action = db.run((for { _ <- table1.filter(_.id1 === id).delete _ <- table2.filter(_.id2=== id).delete } yield ()).transactionally) val result = Await.result(action, Duration.Inf) 语句,并在Future中捕获结果(不使用Await)?

这有效(但使用Await)

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

然而,这不会打印任何内容:

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

  }
}

更新

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

<TextView
        android:id="@+id/tv1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="Customer Service"
        android:textAlignment="center"
        android:textSize="15sp"
        android:clickable="true"
        android:linksClickable="true"
        android:autoLink="web"
        android:background="@drawable/about_us_selector"
        android:textColor="@color/about_us_color" />

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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

那么如何解决这个问题?

您可以将db.close移动到future.map或更好,让play-slick为您处理数据库连接。

旁注

您应该关闭other question并相应地更新此帖子。