scala - Scala Future 中包装的 JDBC 调用
问题描述
我正在编写一个 Akka HTTP Web API,它使用 OJDBC 连接到一个 Oracle 数据库实例。
据我所知,没有用于连接数据库的异步 JDBC API,也没有回调实现,因此,必须阻塞进程线程才能完成调用。
我的问题是:拥有 Akka HTTP 自然允许使用 Scala Future 处理请求,将数据库调用简单地包装到 Scala Future 中是否是个好主意?等待数据库响应时底层线程是否空闲?
解决方案
等待数据库响应时底层线程是否空闲? 是的,线程被阻塞直到 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 }
推荐阅读
- apache-flink - 如何在 Mesos Flink 集群中实现 JobManager 高可用?
- c# - 将两个二维数组混合为 1 个二维数组
- swift - 使用 swift 类附加到字典
- database-design - 数据库设计新手,寻求建议
- excel - 将多个工作表中的数据合并到一张工作表中
- interface - 允许立即执行单元块的开发接口术语
- clickhouse - 当其中一个分片服务器关闭时,是否有某种方法可以使分布式表仍可用于查询?
- css - 如何使用css改变图像中某种颜色的像素?
- php - PHP - MySQL:如何按日期选择数据分组
- swift - 删除类型别名 Swift 数组中的元素