【问题标题】:Releasing connections from connection pool从连接池中释放连接
【发布时间】:2017-05-19 06:17:58
【问题描述】:

在我们的代码中(通过计时器作为计划作业运行),我们有并行运行的线程来执行数据库操作。这里的问题是每个线程都通过 Hibernate 工厂启动连接。这些连接在每次数据库操作后都会关闭,但仍会存储在连接池中(作为 INACTIVE)。只有在作业/主进程被杀死后,所有连接才会被释放。有没有办法在数据库操作后从连接池中释放连接。当我们使用 cron 作业而不是计时器时,进程会自动终止,但我们在这里不需要 cron。 请帮助我们解决这个问题,因为我们已经接近生产版本。 注意:我们是在 QA 测试工作负载繁重时才知道这一点的,每次负载都会拉出新的连接。

【问题讨论】:

  • 听起来像是连接泄漏而不是池。
  • 我们也怀疑过。但是我们已经检查了代码,并确保我们已经关闭了所有连接。发生的情况是,当我们关闭连接时,它会返回池而不是释放,并且只有在邮件线程被终止时才会释放池。那么我们可以在不退出进程的情况下释放池吗?

标签: java connection connection-pooling


【解决方案1】:

您需要限制在线程池中创建的线程数。

dotConnect for Oracle 使用连接池。 OracleConnection 连接字符串具有 Pooling 参数。如果 Pooling=true(默认值),连接关闭后不删除,而是放到池中。当打开具有相同连接字符串的新连接时,它会从池中取出(如果有空闲连接),而不是创建新连接。这提供了显着的性能改进。如果您使用 800 个连接,每个连接 10-15 秒,并且只有几个不同的连接字符串,您可能没有 800 个实际连接。关闭的连接将被放入池中,当打开具有相同连接字符串的新连接时,它们将从池中取出。在这种情况下,不会打开其他连接。

您可以通过将“Pooling=false”添加到连接字符串来禁用池。在这种情况下,将从内存中删除连接并释放会话。但是,这可能会导致性能损失。

池很可能不会导致创建过多会话。尝试使用池测试您的应用程序。如果会话数太大,您可以禁用池。

更多信息请参考http://www.devart.com/dotconnect/oracle/docs/FAQ.html#q54

【讨论】:

  • 我们不能这样做,因为它是现有的遗留设计,人们现在不想改变任何东西。还有其他建议吗?像中断线程或杀死线程会从池中释放连接吗?池连接何时释放?
  • 线程永远不会被杀死或停止。您需要限制创建的线程数。所以另一个选择是在你已经在做的工作完成后关闭连接。您使用的是哪个数据库?检查文档是否可以限制可以控制在 db 端创建的连接数
  • 我们使用的是 oracle 11g。是的,我们可以通过线程池大小和其他参数进行限制。这里的另一个问题是每次进行数据库调用时都会启动会话工厂,而不是作为单例进行跨应用程序的通用使用。此外,如果我限制,线程必须等待其他线程释放连接。在不知道如何释放池连接的情况下遇到死锁。任何手动释放池连接的选项?
  • 请参考答案
  • Bhuvan .. 得到了修复.. 这是一个愚蠢的错误.. 我找到了一个中间解决方案。我减少了最小和最大连接以及将连接从池中释放到 1 的超时......这有助于我获得稳定数量的连接。现在我们在某些地方重构了代码以使用共享会话工厂....这大大减少了连接数!!非常感谢您的建议...我们尚未对其进行全面测试... :)
【解决方案2】:

我找到了问题的根本原因,也找到了解决方案。 根本原因是连接数设置为最小值和最大值以及超时参数。 最小值为 5,最大值为 20,超时时间为 800 秒。但是工作计划每分钟运行一次。由于配置,连接未在几分钟内正确释放。 另一个问题是我们的代码没有将会话工厂用作单例,而是为每个线程进行初始化。由于资源未共享,每个会话工厂默认创建 5 个连接,最多扩展至 20 个。由于在释放连接之前超时也较高,因此下一组作业开始并创建自己的一组新连接。 最后,池满了,oracle 变得不可用。

我们通过共享会话对象并将超时设置为较小的值来解决此问题,以便从池中释放连接。

【讨论】:

    猜你喜欢
    • 2014-08-06
    • 2013-05-01
    • 2016-10-24
    • 2012-04-22
    • 2015-12-04
    • 2014-05-07
    • 2015-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多