我应该每个任务有一个数据库连接还是一个连接?

时间:2015-09-28 15:21:04

标签: java multithreading postgresql servlets concurrency

我有一个Java服务器和PostgreSQL数据库。

有一个后台进程每秒查询(插入一些行)数据库2..3次。并且有一个servlet每个请求一次查询数据库(也插入一行)。

我想知道我应该为它们分别设置Connection个实例,还是在它们之间共享一个Connection实例? 这甚至也重要吗?或者PostgreSQL JDBC驱动程序内部只是将所有请求发送到统一池?

我应该为每个servlet请求线程创建一个新的Connection实例吗?或者为每个servlet线程共享一个Connection实例并保持打开整个运行时间?

通过单独我的意思是每个线程都创建自己的Connection实例,如下所示:

Connection connection = DriverManager.getConnection(url, user, pw);

2 个答案:

答案 0 :(得分:4)

如果您使用单个连接并共享它,一次只有一个线程可以使用它而其他线程将阻止,这将严重限制您的应用程序可以完成的工作量。使用连接池意味着线程可以拥有自己的数据库连接,并可以对数据库服务器进行并发调用。

请参阅postgres文档"Chapter 10. Using the Driver in a Multithreaded or a Servlet Environment"

  

许多JDBC驱动程序的问题是只有一个线程可以使用   任何时候连接---否则线程可以发送查询   而另一个人正在收到结果,这可能会导致严重   混乱。

     

PostgreSQL™JDBC驱动程序是线程安全的。因此,如果你的   应用程序使用多个线程,然后您不必担心   复杂的算法,以确保只有一个线程使用数据库   一段时间。

     

如果某个线程在另一个线程正在使用时尝试使用该连接   它会等到另一个线程完成其当前   操作。如果操作是常规SQL语句,那么   操作包括发送语句和检索任何语句   ResultSet(完整)。如果是快速路径呼叫(例如,读取块)   从一个大的对象)然后它包括发送和检索   各自的数据。

     

这适用于应用程序和applet,但可以导致性能   servlet的问题。如果您有多个线程执行查询   然后每个人都会暂停。为了解决这个问题,建议您创建   一个连接池。当线程需要使用数据库时,   它向Manager类询问Connection对象。经理递了一个   与线程的自由连接并将其标记为忙。如果是免费的   连接不可用,它打开一个。一旦线程有   使用连接完成后,它将它返回给管理员即可   然后关闭它或将其添加到池中。经理也会   检查连接是否仍然存在并将其从池中删除   如果死了连接池的缺点是它增加了   服务器上的负载,因为为每个会话创建了一个新会话   连接对象。这取决于您和您的应用程序   要求。

答案 1 :(得分:1)

根据我的理解,您应该将此任务推迟到容器以管理连接池。

正在使用Servlet,它将在Servlet容器中运行,而我所知道的所有主要Servlet容器都提供连接池管理。

另见