从连接池中释放连接

Releasing connections from connection pool

在我们的代码中(通过计时器作为计划作业运行),我们有线程 运行 并行执行数据库操作。这里的问题是每个线程都通过 Hibernate 工厂启动连接。这些连接在每次数据库操作后关闭,但仍然存储在连接池中(作为非活动状态)。只有在 job/main 进程 killed.Is 之后,所有连接才会被释放,即使是在数据库操作之后,也可以从连接池中释放连接。当我们使用 cron 作业而不是计时器时,进程会自动终止,但我们这里不需要 cron。 请帮助我们解决这个问题,因为我们已经接近生产发布。 注意:我们是在 QA 对作业进行重负载测试时了解到这一点的,并且对于每个负载都会拉取新的连接。

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

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

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

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

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

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

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