简体   繁体   English

Java中有多少个JDBC连接?

[英]How many JDBC connections in Java?

I have a Java program consisting of about 15 methods. 我有一个由大约15种方法组成的Java程序。 And, these methods get invoked very frequently during the exeuction of the program. 并且,在程序的执行期间非常频繁地调用这些方法。 At the moment, I am creating a new connection in every method and invoking statements on them (Database is setup on another machine on the network). 目前,我正在每个方法中创建一个新连接并在其上调用语句(数据库在网络上的另一台机器上设置)。

What I would like to know is: Should I create only one connection in the main method and pass it as an argument to all the methods that require a connection object since it would significantly reduce the number of connections object in the program, instead of creating and closing connections very frequently in every method. 我想知道的是:我应该在main方法中只创建一个连接,并将其作为参数传递给需要连接对象的所有方法,因为它会显着减少程序中连接对象的数量,而不是创建并且在每种方法中经常关闭连接。

I suspect I am not using the resources very efficiently with the current design, and there is a lot of scope for improvement, considering that this program might grow a lot in the future. 我怀疑我没有在当前设计中非常有效地使用资源,并且考虑到该程序将来可能会增长很多,因此还有很大的改进空间。

Yes, you should consider re-using connections rather than creating a new one each time. 是的,您应该考虑重新使用连接,而不是每次都创建一个新连接。 The usual procedure is: 通常的程序是:

  • make some guess as to how many simultaneous connections your database can sensibly handle (eg start with 2 or 3 per CPU on the database machine until you find out that this is too few or too many-- it'll tend to depend on how disk-bound your queries are) 猜测你的数据库可以合理处理多少个同时连接(例如,在数据库机器上以每个CPU 2或3开始,直到你发现它太少或太多 - 它往往取决于磁盘的方式 - 你的查询是)
  • create a pool of this many connections: essentially a class that you can ask for "the next free connection" at the beginning of each method and then "pass back" to the pool at the end of each method 创建这么多连接的 :本质上是一个类,你可以在每个方法的开头请求“下一个空闲连接”,然后在每个方法结束时“回传”到池中
  • your getFreeConnection() method needs to return a free connection if one is available, else either (1) create a new one, up to the maximum number of connections you've decided to permit, or (2) if the maximum are already created, wait for one to become free 你的getFreeConnection()方法需要返回一个空闲连接(如果有),否则(1)创建一个新连接,最多允许你决定允许的最大连接数,或者(2)如果已经创建了最大连接数,等待一个人获得自由
  • I'd recommend the Semaphore class to manage the connections; 我建议使用Semaphore类来管理连接; I actually have a short article on my web site on managing a resource pool with a Semaphore with an example I think you could adapt to your purpose 我实际上在我的网站上有一篇关于使用Semaphore管理资源池的简短文章,我想你可以适应你的目的

A couple of practical considerations: 一些实际考虑因素:

  • For optimum performance, you need to be careful not to "hog" a connection while you're not actually using it to run a query . 为了获得最佳性能,您需要注意不要在实际使用它来运行查询时“占用”连接 If you take a connection from the pool once and then pass it to various methods, you need to make sure you're not accidentally doing this. 如果您从池中获取一次连接然后将其传递给各种方法,则需要确保您不会意外地执行此操作。
  • Don't forget to return your connections to the pool! 不要忘记将您的连接返回游泳池! (try/finally is your friend here...) (尝试/终于是你的朋友......)
  • On many systems, you can't keep connections open 'forever' : the O/S will close them after some maximum time. 在许多系统中,您无法“永久”保持连接打开 :操作系统将在最长时间后关闭它们。 So in your 'return a connection to the pool' method, you'll need to think about 'retiring' connections that have been around for a long time (build in some mechanism for remembering, eg by having a wrapper object around an actual JDBC Connection object that you can use to store metrics such as this) 因此,在“返回与池的连接”方法中,您需要考虑已经存在很长时间的“退休”连接 (构建一些记忆机制,例如通过在实际JDBC周围设置包装器对象)可用于存储此类指标的连接对象)
  • You may want to consider using prepared statements. 您可能需要考虑使用预准备语句。
  • Over time, you'll probably need to tweak the connection pool size 随着时间的推移,您可能需要调整连接池大小

You can either pass in the connection or better yet use something like Jakarta Database Connection Pooling. 您可以传递连接,也可以更好地使用Jakarta数据库连接池等。 http://commons.apache.org/dbcp/ http://commons.apache.org/dbcp/

You should use a connection pool for that. 您应该使用连接池。

That way you could ask for the connection and release it when you are finish with it and return it to the pool 这样你可以要求连接并在完成后将其释放并将其返回池中

If another thread wants a new connection and that one is in use, a new one could be created. 如果另一个线程想要一个新连接并且正在使用该连接,则可以创建一个新连接。 If no other thread is using a connection the same could be re-used. 如果没有其他线程正在使用连接,则可以重复使用该连接。

This way you can leave your app somehow the way it is ( and not passing the connection all around ) and still use the resources properly. 这样你就可以以某种方式离开你的应用程序(而不是四处传递连接)并仍然正确地使用资源。

Unfortunately first class ConnectionPools are not very easy to use in standalone applications ( they are the default in application servers ) Probably a microcontainer ( such as Sping ) or a good framework ( such as Hibernate ) could let you use one. 不幸的是,第一类ConnectionPools在独立应用程序中并不是很容易使用(它们是应用程序服务器中的默认设置)可能是一个微容器(如Sping)或一个好的框架(如Hibernate)可以让你使用它。

They are no too hard to code one from the scratch though. 尽管如此,从头开始编写代码并不难。

:) :)

This google search will help you to find more about how to use one. 此谷歌搜索将帮助您找到有关如何使用它的更多信息。

Skim through 快速浏览

Many JDBC drivers do connection pooling for you, so there is little advantage doing additional pooling in this case. 许多JDBC驱动程序会为您执行连接池,因此在这种情况下执行其他池的优势很小。 I suggest you check the documentation for you JDBC driver. 我建议你查看JDBC驱动程序的文档。

Another approach to connection pools is to 连接池的另一种方法是

  • Have one connection for all database access with synchronised access. 通过同步访问为所有数据库访问建立一个连接。 This doesn't allow concurrency but is very simple. 这不允许并发,但非常简单。
  • Store the connections in a ThreadLocal variable (override initialValue()) This works well if there is a small fixed number of threads. 将连接存储在ThreadLocal变量中(覆盖initialValue())如果存在少量固定数量的线程,则此方法很有效。

Otherwise, I would suggest using a connection pool. 否则,我建议使用连接池。

If your application is single-threaded, or does all its database operations from a single thread, it's ok to use a single connection. 如果您的应用程序是单线程的,或者从单个线程执行所有数据库操作,则可以使用单个连接。 Assuming you don't need multiple connections for any other reason, this would be by far the simplest implementation. 假设您出于任何其他原因不需要多个连接,这将是迄今为止最简单的实现。

Depending on your driver, it may also be feasible to share a connection between threads - this would be ok too, if you trust your driver not to lie about its thread-safety. 根据您的驱动程序,在线程之间共享连接也是可行的 - 如果您相信您的驱动程序不要对其线程安全性撒谎,这也可以。 See your driver documentation for more info. 有关详细信息,请参阅驱动程序文档

Typically the objects below "Connection" cannot safely be used from multiple threads, so it's generally not advisable to share ResultSet, Statement objects etc between threads - by far the best policy is to use them in the same thread which created them; 通常,“连接”下面的对象不能安全地从多个线程中使用,因此通常不建议在线程之间共享ResultSet,Statement对象等 - 到目前为止,最好的策略是在创建它们的同一线程中使用它们; this is normally easy because those objects are not generally kept for too long. 这通常很容易,因为这些物体一般不会保存太久。

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

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