在对基于 JPA
的 DAO
层进行压力测试时(每个在单独的线程中同时运行 500 个同步更新)。我遇到了以下情况 - 系统总是卡住无法取得任何进展。
问题是,在某个时刻任何线程都没有可用的连接,因此正在运行的线程无法取得任何进展。
我对此进行了一段时间的研究,根源是我的一个 JPA DAO
中 add
方法的 REQUIRES_NEW
注释。
所以场景是:
- 测试开始从
ConnectionPool
获取新的Connection
以启动事务。 - 经过一些初始阶段后,我在
DAO
上调用add
,导致它从ConnectionPool
请求另一个Connection
> 没有,因为当时所有连接
都是通过并行运行的测试获取的。
我尝试使用数据源配置
c3p0
卡住了DBCP
卡住BoneCP
卡住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%。
最佳答案
如何配置获取连接的超时时间?如果在 2 秒内无法获得连接,池将中止并抛出异常。
另请注意,REQUIRES
更为典型。通常,您希望调用链共享事务,而不是为链中的每个新调用启动新事务。
关于java - 用于排除 REQUIRES_NEW 方法上的死锁的数据源配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13791322/