java连接池,多线程批处理中的最大连接数是多少?

标签 java spring atomikos

我有一个Java批处理,它对一个大结果集进行选择(我使用Spring回调处理程序处理元素)。 回调处理程序将任务放入固定线程池中来处理该行。 我的池大小固定为 16 个线程。 结果集包含大约 100k 元素。 所有数据库访问代码均通过 JdbcTemplate 或 Hibernate/Spring 处理,不存在手动连接管理。 我尝试过使用 Atomikos 和 Commons DBCP 作为连接池。

现在,我认为连接池中的最大连接数为 17 个就足以完成该批处理。 1 个用于选择,16 个用于连接池中更新某些行的线程。然而,这似乎太天真了,因为我必须指定一个更大的最大池大小(没有尝试过确切的值),首先我尝试了 50,它在我的本地 Windows 机器上工作,但在我们的 Unix 测试环境上似乎不够。我必须指定 128 才能使其工作(同样,我什至没有尝试 50 到 128 之间的值,我直接选择了 128)。

这正常吗?我缺少连接池中的一些基 native 制吗?我发现很难调试它,因为我不知道如何查看打开的连接会发生什么。我尝试了各种 log4j 设置,但没有得到任何满意的结果。

编辑,附加信息:当连接池大小似乎太低时,批处理似乎会挂起。如果我对进程执行 jstat,我可以看到所有线程都在等待新连接。起初,我没有在 dbcp 连接池上指定 maxWait 属性,这会导致线程无限期地等待新连接,并且我注意到批处理一直挂起。所以没有释放任何连接。然而,这只发生在处理 +-70k 行之后,这以某种方式消除了我最初的连接泄漏预感。

edit2:我忘了提及我已经重写了任务中的更新部分。我在 ConcurrentLinkedQueue 中 qeueu 更新,然后清空 1000 个元素。所以我实际上只做了大约 100 次更新。

edit3:我正在使用 Oracle,并且正在使用并发实用程序。所以我有一个配置了固定池大小 16 的执行器。我在这个执行器上提交我的任务。我不会在任务中手动使用连接,我使用线程安全的 jdbctemplate 并要求它从连接池中获取连接。我想 Spring/DBCP 处理连接/线程问题。

最佳答案

如果您使用的是Linux,您可以尝试使用MySql管理员以图形方式监控您的连接状态,前提是您使用的是MySQL。

无论如何,对于大型企业应用程序来说,即使 100 个连接也并不罕见,每分钟处理几千个请求。

但是如果请求较低或者每个请求不需要唯一的事务,那么我建议您调整线程内的操作。

也就是说,你如何将 100k 元素分配给 16 个线程? 如果每次从共享位置(或缓冲区)读取一行时都尝试获取连接,则预计需要时间。

看看这是否有帮助。

  1. 获取连接
  2. 对于每个元素,直到缓冲区大小变为零
  3. 处理它。
  4. 如果您需要更新,
  5. 开启交易
  6. 更新
  7. 提交/回滚事务
  8. 转到步骤 2
  9. 释放连接

您可以使用java.util.concurrent collections来同步缓冲区

不要为每个元素使用一个 Runnable/Callable。这会降低性能。 另外你是如何创建线程的?使用 Executors 来运行您的可运行/可调用。另请记住,数据库连接不应跨线程共享。因此,一次在 1 个线程中使用 1 个连接。

例如。创建一个 Executor 并提交 16 个 runnalble,每个 runnalble 都有自己的连接。

关于java连接池,多线程批处理中的最大连接数是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9503930/

相关文章:

java - 在字符串连接中使用 super 时编译失败

java - 使用带超时的 sping 的 restTemplate,如何检测超时?

java - 如何修复 UnfinishedStubbingException

java - 如何自动记录 @Entity 上的任何更改?

java - mvn clean install 适用于 springboot 1.3.1 但不适用于 2.2.2

java - 如何使用Spring Boot并行执行SQL查询?

mysql - Spring 3 - Hibernate 3 - 查询多个 MySQL 数据库

Java - 屏幕截图窗口在可运行的 jar 文件中不起作用

transactions - JTA 是否可以跨多个线程工作?

postgresql - Atomikos JTA 事务管理器 'Purging orphaned entry from log' 登录输出