问题 是否可以通过Java NIO非阻塞套接字异步访问数据库?


我想以非阻塞的方式访问数据库,换句话说,我将通过套接字发送SQL请求并通过同一个套接字读取查询响应 异步。这意味着我只能在套接字可用时读取数据(Java NIO SocketChannel)所以我永远不会阻止。

我可能错了,但据我所知,数据库的JDBC驱动程序都使用阻塞套接字。

即使我必须执行返回100万行的查询,我也可以异步执行,接收行在套接字缓冲区中可用的行。

我的目标是执行SQL查询而不会阻塞(即不会产生延迟)。 使用单独的线程不是一种选择。我需要在网络线程(NIO选择器线程)内执行此操作。

有没有人成功这样做或者可以推荐一种不涉及额外线程的方法?


6040
2018-01-24 17:16


起源

为什么使用单独的线程不是一个选项?从另一个线程执行异步查询会非常简单。 - erickson
@erickson使用另一个线程不是一个选项,因为我没有在我的机器上备用另一个线程的cpu核心。如果您必须同时进行2个查询,这也行不通。该线程将阻塞等待第一个查询的结果完成。然后,您必须将第二个查询放入队列或跨越另一个线程。做我想做的事情在数据库方面实现并发,而不是在我这边。但同样,这是另一个问题的主题。假设你正在面试,并被告知另一个线程不是一个选项:) - Richard Bradley
你有一些关于线程的误解。对于在网络I / O上阻塞的线程,您不需要一个核心。它不在 可运行 state,并且不会考虑在任何可用的核心上进行调度。大多数系统在几个内核上成功运行了数百个线程。同时执行许多异步查询也不是问题。这就是为什么数据库连接池是一个东西。 - erickson
@erickson你在不知道任何关于场景的事情的情况下,正在做出关于场景的假设。我不能让1000个线程在少数核心中进行上下文切换,因为我的系统对延迟非常敏感。我休息一下。 - Richard Bradley
这就是我问的原因,并回复了所提供的信息。 - erickson


答案:


这是可能的,但不是JDBC。除非你想使用原始 SocketChannel 接口并自己解析结果,我知道的JVM上唯一的异步数据库驱动程序 https://github.com/mauricio/postgresql-async (尽管名称也支持MySQL)。它们是用Scala编写的,但它应该是 可能 从Java调用它们(因为它是一种JVM语言),但我不能说API对Java有多友好。


11
2018-01-24 17:23



谢谢。您是否知道数据库的套接字协议是否易于通话,因此我可以在不使用任何JDBC驱动程序的情况下通过网络执行查询? - Richard Bradley
我不知道那种方式。 - lmm
从Java应用程序调用此驱动程序是非常可能和容易的。我已经使用了一段时间了。 - Dave Taubler


如果您编写自己的驱动程序,那么对于大多数数据库来说肯定可以这样做。

但是,我不知道有任何驱动程序“开箱即用”。


0
2018-01-24 17:20