运行 交易并在 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 为您处理数据库连接。
旁注
您应该关闭 并相应地更新此线程。
如何在 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 为您处理数据库连接。
旁注
您应该关闭