关于这个问题,自问自答,以下是我找到的2个参考思路:
参考1:
One of the problems with conventional database drivers is that
they do not allow an application to execute
(i) multiple independent queries to a database in parallel
(ii) queries to multiple databases in parallel
without using additional threads.
A
second problem with these drivers is that they do not work well with
web servers that use an event-driven architecture where a single thread
manages multiple requests. Most drivers have a single thread of
execution which blocks on every request. As a result, having a single
thread manage multiple requests means the thread blocks on every
request to the driver.
Yes, as you have described, one approach
to asynchronous DB interaction is to push requests onto a queue and
process them using a thread pool. Here we still rely on the underlying
(blocking) driver for the actual communication to the DB. The
limitations of this approach[1,2,3,4] are:
(i) for eg. in JDBC, the Connection is not thread safe in many of the driver implementations.
(ii)
even if it is thread safe, sharing a single Connection with multiple
threads is not beneficial since the important methods are synchronized,
thereby allowing only one query at a time on one connection.
Using one connection per thread is an option, but cannot be used if the queries have to be a part of one transaction.
The
alternative is to use non-blocking socket I/O. Non-blocking I/O
enables pipelining to improve the performance of issuing multiple
requests to a database, especially over high latency connections.
Pipelining provides the ability to send more than one request without
waiting for the response from previous requests.
To conclude, I
strongly believe that using non-blocking socket I/O for asynchronous
database drivers has advantages over using a thread-pool with
conventional database drivers.
(i) Queries can be sent to the database immediately instead of waiting to be executed in a second thread
(ii) Multiple requests can be pipelined which also improves performance in most cases.
参考2:
Most
interactions that a client application has with a database server are
of the form request -> response. Furthermore, almost all
communications between a client and a server are in the context of a
connection. Therefore it is the easiest programming model to expose an
API that appears to be blocking on the client side. The underlying
communications are not necessarily blocking I/O, it is perfectly
possible that the underlying communications is multiplexed I/O of
multiple logical database connections to the server and that is most
likely asynchronous.
Realize that on the database side (server side)
the socket is most likely asynchronous and the server is most likely
using non-blocking I/O on it.
Also, ODBC does support an asynchronous mode of operation though databases that support it do so to varying degrees.
If
you would like an asynchronous database interface for your application
it isn't hard for you to do it if you follow a couple of simple guidelines.
1.
most database interfaces won't support request queueing so you have to
ensure that no requests are outstanding when you issue a new request;
the notable exception to this is the handling of out of band requests
like cancel.
2.
implement a thread or group of threads in your application to be the
connection handlers and implement some non-blocking communication
mechanism between your application thread and those threads (like a pair
of queues).
3.
Queue all your database operations to the database-worker thread and
use some non-blocking mechanism to get the results from the result
queue.
Unless there's something very special about your
application architecture though, I'm not sure how much this kind of
thing will benefit your performance but I'd love to know more about why
you think there will be an improvement in performance or if you
implement the little approach above, what improvement it did give you.
出处:Quora