Ste*_*ury 155 java asynchronous scala jdbc nonblocking
我想知道是否有办法对数据库进行异步调用?
例如,假设我有一个需要很长时间才能处理的大请求,我想发送请求并在请求返回值时接收通知(通过传递监听器/回调或其他东西).我不想阻止等待数据库回答.
我不认为使用线程池是一种解决方案,因为它不能扩展,在繁重的并发请求的情况下,这将产生大量的线程.
我们正面临网络服务器的这种问题,我们通过使用select/poll/epoll系统调用找到了解决方案,以避免每个连接有一个线程.我只是想知道如何在数据库请求中使用类似的功能?
注意:我知道使用FixedThreadPool可能是一个很好的解决办法,但我很惊讶没有人开发出一个真正异步的系统(没有使用额外的线程).
**更新**
由于缺乏真正实用的解决方案,我决定自己创建一个库(finagle的一部分):finagle-mysql.它基本上解码/解码mysql请求/响应,并在引擎盖下使用Finagle/Netty.即使有大量的连接,它也能很好地扩展.
joh*_*lon 158
我不明白在Actors,执行器或其他任何东西中包含JDBC调用的任何提议方法如何在这里有所帮助 - 有人可以澄清.
当然,基本问题是JDBC操作阻塞了套接字IO.当它执行此操作时,它会阻止Thread运行 - 故事结束.无论你选择使用哪种包装框架,最终都会有一个线程在每个并发请求中保持繁忙/阻塞状态.
如果底层的数据库驱动程序(MySQL的?)提供拦截套接字创建的一种手段(见的SocketFactory),那么我想这将有可能建立在JDBC API之上的异步事件驱动的数据库层,但我们不得不封装整个JDBC在事件驱动的外观后面,并且该外观看起来不像JDBC(在事件驱动之后).数据库处理将在与调用者不同的线程上发生异步,并且您必须弄清楚如何构建不依赖于线程关联的事务管理器.
像我提到的方法之类的东西甚至允许一个后台线程处理并发JDBC exec的负载.实际上,您可能会运行一个线程池来使用多个核心.
(当然,我不评论原题的逻辑只是意味着一个场景,并发与封闭插座IO可能没有选择器模式的用户的响应 - 简单的只是制定出典型的JDBC并发性,并把在正确大小的连接池中).
看起来MySql可能会像我建议的那样做点什么--- http://code.google.com/p/async-mysql-connector/wiki/UsageExample
Vas*_*iuk 42
通过JDBC 对数据库进行异步调用是不可能的,但您可以使用Actors 对JDBC进行异步调用(例如,actor通过JDBC调用DB,并在调用结束时向第三方发送消息),或者,如果你喜欢CPS,使用流水线期货(承诺)(一个很好的实现是Scalaz Promises)
我不认为使用线程池是一种解决方案,因为它不能扩展,在繁重的并发请求的情况下,这将产生大量的线程.
默认情况下,Scala actor是基于事件的(不是基于线程的) - 延续调度允许在标准JVM设置上创建数百万个actor.
如果您的目标是Java,那么Akka Framework是一个Actor模型实现,它具有适用于Java和Scala的良好API.
除此之外,JDBC的同步特性对我来说非常有意义.数据库会话的成本远远高于被阻止的Java线程(在前端或后台)和等待响应的成本.如果您的查询运行的时间太长以至于执行程序服务的功能(或包装Actor/fork-join/promise并发框架)对您来说是不够的(并且您消耗了太多线程),那么首先应该考虑一下数据库加载.通常,数据库的响应速度很快,并且使用固定线程池支持的执行程序服务是一个足够好的解决方案.如果你有太多长时间运行的查询,你应该考虑提前(预)处理 - 比如每晚重新计算数据或类似的东西.
Tom*_*ros 11
也许你可以使用JMS异步消息系统,它可以很好地扩展,恕我直言:
将消息发送到队列,订阅者将接受该消息,并运行SQL进程.您的主进程将继续运行并接受或发送新请求.
当SQL进程结束时,您可以以相反的方式运行:使用进程的结果向ResponseQueue发送消息,并且客户端上的侦听器接受它并执行回调代码.
JDBC中没有直接支持,但您有多个选项,如MDB,Java 5的Executors.
"我不认为使用线程池是一种解决方案,因为它不能扩展,在繁重的并发请求的情况下,这将产生大量的线程."
我很好奇为什么一个有限的线程池不会扩展?它是一个池而不是每个请求的线程,每个请求产生一个线程.我在重负载webapp上使用它已经有一段时间了,到目前为止我们还没有看到任何问题.