2016-12-01 59 views
0

如何在Slick 3.1.x中运行transactionally语句,并将结果捕获到Future中(不使用等待)?在事务中运行并检索未来的结果

此作品(但使用等待)

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) } 

UPDATE

这是从没有按程序采取的实际代码没有工作。它打印“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 

    } 
} 
+0

你的代码没问题。也许应用程序在未来完成之前退出。在映射未来之后尝试添加一些'Thread.sleep'来看看它是否有效。 –

+0

对于像'println'这样的副作用函数(返回'Unit''),最好使用'foreach'(而不是'map')。 –

+0

如果'future.map'没有启动它,因为未来可能是失败的,请尝试附加'.recover'或'.recoverWith'。 –

回答

1

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

那么如何解决这个问题呢?

要么您将db.close转换为future.map或更好,您让play-slick为您处理db连接。

旁注

应关闭other question和更新这个帖子据此来代替。

1

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

尝试添加一些睡眠你的代码在你的第二个样本,你会看到它正在打印。这绝对是你不会在你的实际代码中做什么(这个睡眠),但它会告诉你它的工作原理应该如此。

+0

我在Play 2.5中运行它,而不是单机版。出于某种原因'future.map'不会执行 – ps0604

+0

您能否粘贴更大的代码?就像这与您的控制器在Play中的处理方式相互作用一样? –

+0

请参阅更新 – ps0604