我想知道是否有一种方法可以对数据库进行异步调用吗?
例如,假设我有一个很大的请求,需要很长时间来处理,我想发送请求并在请求将返回值时(通过传递侦听器/回调等)接收通知。我不想阻塞等待数据库答复。
我不认为使用线程池是一种解决方案,因为它无法扩展,在大量并发请求的情况下,这会产生大量线程。
我们正在面对网络服务器的此类问题,并且我们已经找到解决方案,方法是使用select / poll / epoll系统调用来避免每个连接只有一个线程。我只是想知道如何在数据库请求中具有类似的功能?
注意:我知道使用FixedThreadPool可能是一个很好的解决方法,但是令我惊讶的是,没有人开发出真正异步的系统(无需使用额外的线程)。
更新 由于缺乏实际可行的解决方案,我决定自己创建一个库(finagle的一部分):finagle- mysql。它基本上解码/解码mysql请求/响应,并在后台使用Finagle / Netty。即使有大量连接,它的扩展性也非常好。
我不明白在Actor,executor或其他任何东西中包装JDBC调用的提议方法如何能在这里提供帮助-有人可以澄清一下。
当然,基本问题是JDBC操作在套接字IO上阻塞。执行此操作时,它将阻止线程在故事结尾运行。无论选择哪种包装框架,使用它最终都会导致每个并发请求保持一个线程繁忙/阻塞。
如果基础数据库驱动程序(MySql?)提供了一种方法来拦截套接字的创建(请参见SocketFactory),那么我想可以在JDBC api之上构建异步事件驱动的数据库层,但是我们必须封装整个JDBC在事件驱动的外观后面,并且该外观看起来不像JDBC(在事件驱动之后)。数据库处理将在与调用方不同的线程上异步发生,并且您必须弄清楚如何构建不依赖线程亲和力的事务管理器。
就像我提到的方法一样,它甚至允许单个后台线程处理并发JDBC执行程序的负载。实际上,您可能会运行一个线程池来利用多个内核。
(当然,我不是在评论原始问题的逻辑,只是回答那些暗示在没有选择器模式的情况下,在阻塞套接字IO的情况下并发是可能的- 简单地算出典型的JDBC并发并放入在大小合适的连接池中)。
看起来MySql可能按照我的建议做了一些事情— http://code.google.com/p/async-mysql- connector/wiki/UsageExample