我有一个 Java 批处理,它使用大的结果集进行选择(我使用 Spring 回调处理程序处理元素)。回调处理程序将任务放入固定线程池中以处理该行。我的 poolsize 固定在 16 个线程上。结果集包含大约 100k 个元素。所有数据库访问代码都通过 JdbcTemplate 或 Hibernate/Spring 处理,不存在手动连接管理。我曾尝试使用 Atomikos 和 Commons DBCP 作为连接池。
现在,我认为我的连接池中最多 17 个连接足以完成这批。一个用于选择,16 个用于连接池中更新某些行的线程。然而这似乎太天真了,因为我必须指定一个更大的最大池大小(没有尝试过确切的值),首先我尝试了 50 ,它在我的本地 Windows 机器上工作,但似乎不是在我们的 Unix 测试环境中已经足够了。在那里我必须指定 128 才能使其工作(同样,我什至没有尝试 50 到 128 之间的值,我直接选择了 128)。
这是正常的吗?我缺少连接池的一些基本机制吗?我发现很难调试它,因为我不知道如何查看打开的连接会发生什么。我尝试了各种 log4j 设置,但没有得到任何令人满意的结果。
编辑,附加信息:当连接池大小似乎太低时,批处理似乎挂起。如果我对进程执行 jstat,我可以看到所有线程都在等待新连接。起初我没有在 dbcp 连接池上指定 maxWait 属性,这会导致线程在新连接上无限期地等待,我注意到批处理一直挂起。所以没有释放连接。然而,这只发生在处理 +-70k 行之后,这以某种方式消除了我最初的连接泄漏预感。
edit2:我忘了提到我已经在我的任务中重写了更新部分。我在 ConcurrentLinkedQueue 中查询我的更新,我清空了 1000 个元素。所以我实际上只做了大约 100 次更新。
edit3:我正在使用 Oracle,并且正在使用并发工具。所以我有一个配置为 16 的固定池大小的执行器。我在这个执行器上提交我的任务。我不在我的任务中手动使用连接,我使用线程安全的 jdbctemplate 并询问它来自连接池的连接。我想 Spring/DBCP 处理连接/线程问题。