【问题标题】:DataSource configuration to exclude deadlocks on REQUIRES_NEW methods用于排除 REQUIRES_NEW 方法上的死锁的 DataSource 配置
【发布时间】:2012-12-09 20:11:45
【问题描述】:

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

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

我对此进行了一段时间的调查,根源是我的JPA DAO's 之一中add 方法上的REQUIRES_NEW 注释。

所以场景是:

  1. 测试开始从ConnectionPool 获取新的Connection 以开始事务。
  2. 在某个初始阶段之后,我在我的DAO 上调用add,导致它从ConnectionPool 请求另一个Connection,但没有,因为到那时所有Connections 都被并行占用了运行测试。

我尝试使用 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% 的通过测试。

【问题讨论】:

    标签: java jpa transactions datasource stress-testing


    【解决方案1】:

    如何配置获取连接的超时时间?如果在 2 秒内无法获得连接,池将中止并抛出异常。

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

    【讨论】:

    • 我玩了结帐超时,确实测试开始失败。 2 秒 - 8 % 通过,92 失败 4 秒 - 12 % 通过,6 秒 - 16 % 通过,8 秒 - 26 % 通过,10 秒 - 34 % 通过,12 秒 - 36 % 通过,14 秒 - 40 % 通过, 这并不完美,但仍然更好
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-30
      • 1970-01-01
      • 1970-01-01
      • 2011-01-23
      • 2014-05-24
      • 1970-01-01
      • 2015-05-24
      相关资源
      最近更新 更多