简体   繁体   English

Akka:如何制作非阻塞JDBC请求

[英]Akka: how to make non-blocking JDBC requests

I am brand new to Akka ( Java lib ) and am trying to understand if Akka can be used to make non-blocking requests to JDBC, and if so, what that it would look like. 我是Akka( Java lib )的新手,我试图了解Akka是否可以用来向JDBC发出非阻塞请求,如果是这样,它会是什么样子。 I believe most JDBC drivers open a socket connection and block the thread that created it until a particular JDBC response is received, and so there might not be much Akka can do to help here, but I am wondering if there is a way (perhaps through Futures or Agents?) that Akka could help improve performance, and allow the actor system to continue processing data, while an existing JDBC call is being made and awaiting a response. 相信大多数JDBC驱动程序打开一个套接字连接并阻塞创建它的线程,直到收到一个特定的JDBC响应,所以可能没有太多Akka可以帮助到这里,但我想知道是否有办法(也许通过期货或代理?)Akka可以帮助提高性能,并允许actor系统继续处理数据,同时正在进行现有的JDBC调用并等待响应。

I found this article which is a bit vague/cryptic, but it sounds like futures might be the key here. 我发现这篇文章有点模糊/含糊不清,但听起来未来可能是关键所在。 However that article doesn't really show any meaningful (real-world) code examples, and so I'm still at a loss. 然而,该文章并没有真正展示任何有意义的(真实世界)代码示例,因此我仍然处于亏损状态。 So let's say we have a stored procedure, sp_make_expensive_calculation , that normally takes 10 - 30 seconds to return a response and that is normally called via JDBC like so: 因此,假设我们有一个存储过程sp_make_expensive_calculation ,通常需要10 - 30秒才能返回响应,并且通常通过JDBC调用,如下所示:

String makeExpensiveCalculationSql = "{call sp_make_expensive_calculation(?)}";
callableStatement = dbConnection.prepareCall(makeExpensiveCalculationSql);
callableStatement.setInt(1, 10);

// Could take up to 30 seconds to complete.
callableStatement.executeUpdate();

int answer = callableStatement.getString(2);

Can Akka do anything to help here so that the actor system can continue processing data (and even make other sp_make_expensive_calculation calls) while we wait for the first call to return? Akka可以做任何事情来帮助这里,以便演员系统可以继续处理数据(甚至进行其他sp_make_expensive_calculation调用),同时我们等待第一次调用返回吗?

The general pattern is to use separate execution contexts : one for synchronous database access via JDBC, one for reactive processing. 一般模式是使用单独的执行上下文 :一个用于通过JDBC进行同步数据库访问,一个用于反应式处理。 Also see the Akka futures documentation . 另请参阅Akka期货文档

When you create an actor system it creates its own execution context -- this is the one you use for your normal reactive processing with actors. 当您创建一个actor系统时,它会创建自己的执行上下文 - 这是您用于与actor进行正常反应处理的上下文。 You need to create a second execution context for the JDBC calls. 您需要为JDBC调用创建第二个执行上下文。 You will then pass this execution context to the future factory as shown here in the Akka documentation . 然后,您将把此执行上下文传递给将来的工厂,如Akka文档中所示

In order to be notified when the future has completed, you can (optionally) use the pipe construct (also shown in the previous link, but in the preceeding documentation section). 为了在将来完成时得到通知,您可以(可选)使用管道构造(也显示在上一个链接中,但在前面的文档部分中)。 The effect of the pipe construct is to take the return value of the future, whose type is that of the future's generic type parameter (for example, the result of your query), and post it to the specified actor's mailbox. 管道构造的作用是获取future的返回值,其类型是future的泛型类型参数(例如,查询的结果),并将其发布到指定的actor的邮箱。

The code executed by the future must not modify or even read any mutable data owned by the initiating actor (or any actor, for that matter). 未来执行的代码不得修改甚至读取发起者(或任何参与者)拥有的任何可变数据。 You'll need to tag the result of the future so that when it arrives in the actor's mailbox the actor will be able to associate it with the initial JDBC request. 您需要标记未来的结果,以便当它到达actor的邮箱时,actor可以将它与初始JDBC请求相关联。 Finally, your actor will eventually receive the result and you can continue to process it (subject to Akka's at-most-once delivery guarantees). 最后,你的演员最终会收到结果,你可以继续处理它(根据Akka的最多一次交付保证)。

Note that you don't have to use two execution contexts -- one will also work, but there would be a danger of your database requests consuming all available threads in the execution context. 请注意,您不必使用两个执行上下文-一个也将工作,但仍然会有消耗在执行上下文中的所有可用线程的数据库请求的危险。

You're correct that the JDBC connection will block until the request is through, but if you wrap it in an asynch processor you can allow it to finish and let the main thread continue. 你是正确的,JDBC连接将阻塞,直到请求通过,但如果你将它包装在异步处理器中,你可以允许它完成并让主线程继续。

One way to give the requestor access to the outcome of the JDBC request is by supplying a callback that is invoked when the asynch database process is complete. 让请求者访问JDBC请求结果的一种方法是提供在异步数据库进程完成时调用的回调。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM