2016-12-01 60 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