简体   繁体   English

播放框架+ JDBC +期货

[英]Play Framework + JDBC + Futures

Assuming I obtain a JDBC connection through injection, like so: 假设我通过注入获得了JDBC连接,如下所示:

class SqlQuery  @Inject()(db: Database) extends Controller  { /* .... */ }

And that the pool of connections is large enough, for example 100. Is it possible to create a Future to avoid blocking when running the SQL statement (similar to Slick futures)? 并且连接池足够大,例如100。是否可以创建Future来避免在运行SQL语句时发生阻塞(类似于Slick Futures)? Or the fact that the number of connections in the pool is large means that the SQL statement will not block? 还是池中的连接数很大意味着SQL语句不会阻塞?

Using futures is not synonymous with non-blocking. 使用期货并不等同于非阻塞。 Futures allow you to execute code on another thread, or some type of executor, in general. 通常,使用期货,您可以在另一个线程或某种类型的执行程序上执行代码。 However, the code you execute can still block. 但是,您执行的代码仍会阻塞。

JDBC is a blocking API. JDBC是一个阻塞API。 This means that when you execute a query through JDBC, the calling thread is blocked while it waits for a response from the database. 这意味着,当您通过JDBC执行查询时,调用线程在等待数据库响应时被阻塞。 Another term for this would be synchronous . 另一个术语是同步的 A non-blocking or asynchronous API would accept a response asynchronously, freeing the calling thread from actively waiting for it. 非阻塞或异步 API会异步接受响应,从而使调用线程免于主动等待。 Reactive slick uses it's own driver to accept responses from a database in an asynchronous manner, which means the calling thread can be freed as soon as the query is dispatched to the database. Reactive slick使用它自己的驱动程序以异步方式接受数据库的响应,这意味着只要将查询分派到数据库,就可以释放调用线程。

The difference between the two is this: 两者之间的区别是:

Imagine your application has a database connection pool of size 100, and a fixed thread pool of size 10. Then, let's say you wrap all of your JDBC calls in futures. 想象一下,您的应用程序有一个大小为100的数据库连接池和一个大小为10的固定线程池。然后,假设您将所有JDBC调用包装在将来。 Let's also say that your SqlQuery controller has a method that makes several JDBC calls at the same time. 还要说您的SqlQuery控制器有一个可以同时进行多个JDBC调用的方法。 All of these queries will be run in parallel, until the thread pool is exhausted, which means you would only be able to run 10 queries at the same time at any given moment. 所有这些查询将并行运行,直到线程池耗尽为止,这意味着您将只能在任何给定时刻同时运行10个查询。 While the calling thread would not be blocked by the JDBC calls, the threads executing them would. 虽然调用线程不会被JDBC调用阻止,但是执行它们的线程会阻止。 With enough queries running in parallel, the thread pool would become exhausted and it would no longer matter how many connections were in the pool. 如果有足够多的并行查询运行,则线程池将耗尽,并且池中的连接数不再重要。 You could deal with this by making your thread pool larger, or using a fork join pool that expands as needed, but this could incur performance costs due to the creation of new threads and context switching. 您可以通过增大线程池或使用根据需要扩展的派生联接池来解决此问题,但是由于创建新线程和上下文切换,这可能会导致性能损失。 After all, your CPU is limited. 毕竟,您的CPU是有限的。

Using an asynchronous database driver like reactive slick would not block your limited pool of threads, and you would be able to run as many queries concurrently as you had connections in the pool (100 in this example). 使用像active slick这样的异步数据库驱动程序不会阻塞您有限的线程池,并且您将能够同时运行与池中有连接的情况一样多的查询(在此示例中为100)。 Saving threads from being blocked means saving CPU time that would otherwise be spent just waiting for responses, which means you can use it to continue to handle other requests, etc. 避免线程被阻塞意味着节省CPU时间,否则这些CPU时间将仅用于等待响应,这意味着您可以使用它来继续处理其他请求等。

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

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