java - 用于排除 REQUIRES_NEW 方法上的死锁的数据源配置

标签 java jpa transactions datasource stress-testing

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

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

我对此进行了一段时间的研究,根源是我的一个 JPA DAOadd 方法的 REQUIRES_NEW 注释。

所以场景是:

  1. 测试开始从 ConnectionPool 获取新的Connection 以启动事务。
  2. 经过一些初始阶段后,我在 DAO 上调用 add,导致它从 ConnectionPool 请求另一个Connection > 没有,因为当时所有连接都是通过并行运行的测试获取的。

我尝试使用数据源配置

  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%。

最佳答案

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

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

关于java - 用于排除 REQUIRES_NEW 方法上的死锁的数据源配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13791322/

相关文章:

Java - 为什么 Eclipse 告诉我我的方法必须返回类型 int?

java - 根据生产或测试环境在 Eclipse 中使用不同的 JPA.persistence.xml

go - 如何在golang中使用事务

Android FragmentManager beginTransaction.add 添加 fragment 到隐藏容器

java - 使用 JoinRowSet 时缺少两行

Java - 将字符串拆分为数组

Java Minecraft 插件问题 - 不响应 if 语句?

java - 混合 JTA 和 JDBC 事务

java - JPA 没有 EntityManager 的持久性提供者

sql - Grails 事务(不是基于 GORM,而是使用 Groovy Sql)