我正在编写一个Akka HTTP Web API,该API使用OJDCB连接到Oracle数据库实例。
据我所知,没有异步JDBC API可以连接到数据库,也没有回调实现,因此,必须阻塞进程线程才能完成调用。
我的问题是:让Akka HTTP自然地允许使用Scala Future处理请求,将数据库调用简单包装到Scala Future中是一个好主意吗?在等待数据库响应时基础线程是否空闲?
答案 0 :(得分:4)
等待数据库响应时基础线程是否空闲? 是的,线程被阻塞,直到JDBC调用完成。这不是一件好事,但是在adba准备就绪之前,可能没有更好的选择。
使用 Future 进行阻塞IO 是常见的模式,例如 JDBC 调用。虽然有些事情要考虑。 github上有一篇关于该主题的精彩文章。
总结一下文章中所述的几点:
将您的阻止呼叫包裹在blocking
块中,如下所示:
def fetchUser(id: Long): Future[User] = Future {
blocking { //mark this operation as blocking
...
preparedStatement.execute()
...
}
}
您不应将scala.concurrent.ExecutionContext.Implicits.global
用于进行任何冻结的期货,因为您可能会饿死线程池。您应该为阻塞操作创建一个单独的线程池:
object BlockingIOExecutionContext {
implicit val ec: ExecutionContextExecutor = ExecutionContext.fromExecutor(
Executors.newCachedThreadPool()
) // create seperate thread pool for our blocking operations
}