DataSource配置以排除REQUIRES_NEW方法上的死锁

时间:2012-12-09 20:11:45

标签: java jpa transactions datasource stress-testing

在对基于JPA的{​​{1}}层进行压力测试时(在单独的线程中同时运行500个同步更新)。我遇到了以下问题 - 系统始终无法取得任何进展。

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

我已经对此进行了一段时间的调查,并且我的DAO之一的REQUIRES_NEW方法上的add注释为JPA DAO's

所以场景是:

  1. 测试开始从Connection获取新ConnectionPool以开始交易。
  2. 在初始阶段之后,我在add上致电DAO,导致它从Connection请求另一个ConnectionPool,但没有,因为所有{{1}到那个时候,是通过并行运行测试。
  3. 我尝试使用DataSource配置

    1. Connections卡住了
    2. c3p0卡住了
    3. DBCP卡住了
    4. BoneCP某些请求失败,错误 - 超出了连接数。
    5. 虽然我通过阅读REQUIRES_NEW解决了这个问题,所有DataSource都能很好地工作,但最好的结果似乎是MySQLDataSource,因为它没有卡住而且只是失败了:)

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

      我的问题:

      是否存在可以阻止此REQUIRES_NEW问题的DataSource配置?


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

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

      这是非常主观的。

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

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

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

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