2

JPA在对我的基础层进行压力测试DAO时(在单独的线程中同时运行 500 个同时更新)。我遇到以下问题 - 系统总是卡住无法取得任何进展。

问题是,在某个时候任何线程都没有可用的连接,所以没有运行线程可以取得任何进展。

我已经对此进行了一段时间的调查,根源是REQUIRES_NEWadd的一个JPA DAO's.

所以场景是:

  1. 测试开始获取新Connection的从ConnectionPool开始事务。
  2. 在某个初始阶段之后,我调用addmy DAO,导致它请求另一个没有的,因为到那时,所有这些Connection都是由并行运行的测试进行的。ConnectionPoolConnections

我尝试使用 DataSource 配置

  1. c3p0卡住
  2. DBCP卡住
  3. BoneCP卡住
  4. MySQLDataSource使某些请求失败,并出现错误 - 超出允许的连接数。

虽然我通过阅读 REQUIRES_NEW 解决了这个问题,所有数据源都可以完美地工作,但最好的结果似乎仍然是 MySQLDataSource,因为它没有卡住而只是失败了:)

因此,如果您期望高吞吐量,您似乎根本不应该使用 REQUIRES_NEW。

我的问题:

是否有任何数据源的配置可以防止这个 REQUIRES_NEW 问题?


我在 c3p0 中使用了结帐超时,并且测试开始失败,正如预期的那样。

  • 2 秒 - 8 % 通过
  • 4 秒 - 12 % 通过
  • 6 秒 - 16 % 通过
  • 8 秒 - 26 % 通过
  • 10 秒 - 34 % 通过
  • 12 秒 - 36 % 通过
  • 14/16/18 秒 - 40 % 通过

这当然是非常主观的。

具有简单配置的 MySQLDataSource 提供了 20% 的通过测试。

4

2 回答 2

2

为获取连接配置超时怎么样?如果在 2 秒内无法获得连接,则池将中止并抛出异常。

另请注意,这REQUIRES是更典型的。通常,您希望调用链共享事务,而不是为链中的每个新调用启动新事务。

于 2012-12-09T20:21:48.117 回答
2

可能任何连接池都可以配置为以多种方式处理此问题。最终,所有 REQUIRES_NEW 可能会迫使您的应用程序为每个客户端获取多个连接,这会增加压力测试的压力。如果池挂起,可能是因为它们的连接用完了。如果您设置了足够大的池大小,您可能会解决该问题。或者,正如 Arjan 上面建议的那样,如果客户端必须等待连接,您可以将池配置为“快速失败”而不是无限期挂起。使用 c3p0,其配置参数将是 checkoutTimeout。

当您说连接池“卡住”时,如果没有更多关于究竟发生了什么的信息,这必然是猜测。但是在非常高的并发负载下,对于任何连接池,您要么需要提供大量资源(c3p0 中的高 maxPoolSize + numHelperThreads),要么踢掉多余的客户端(checkoutTimeout),或者让客户端忍受很长时间(但有限! ) 等待时间。

于 2012-12-10T11:00:47.293 回答