【问题标题】:Spring data JPA consumes all the connection objectsSpring data JPA 消耗所有连接对象
【发布时间】:2020-11-23 04:46:58
【问题描述】:

我有一个场景,数据从 excel 表上传到 mysql db。我正在使用弹簧数据 jpa。并且服务在用从 excel 表中获取的数据填充实体以保存在数据库中之后递归地调用实体。这会在特定负载后创建“无法获取 jdbc 连接”。

我尝试使用 @Transactional 来了解优势。然后我正在考虑在代码中手动使用 EntityManager 并控制事务边界,以便实体的所有递归保存调用都发生在一个事务中,从而发生在一个连接对象中。我只是想检查这是否是一个好主意,或者我应该采取任何其他性能更高的方法。不用说无论如何我必须通过实体来做到这一点。

【问题讨论】:

  • 你能显示你的代码吗?您使用的是哪个 MYSQL 引擎? excel中可以有多少数据?
  • 除此之外,您还可以使用以下要求说明来更新问题。如果 excel 包含 10 000 条记录,如果应用程序在 9 000 条记录后出错,1)您是否想要数据库中的这 9 000 条成功记录或 2)您不希望任何记录保存在数据库中,如果插入中途失败

标签: java hibernate spring-data-jpa spring-jdbc spring-transactions


【解决方案1】:

我的回答完全基于这样的假设,即实现需求的方式是错误的,因为问题中没有共享任何代码。

通过您的方法,是的,您将耗尽连接,因为实体填充肯定会比在数据库中持久化该实体要快得多,并且由于您是递归地执行此操作,因此您的应用程序将在某个时间点耗尽连接,如果数据量非常大,数字肯定是这里的一个因素。

我更喜欢的另一种方法是你可以准备你的实体(假设所有数据都用于一个公共实体类)并存储在一个集合中,一旦准备好你就可以使用 saveAll( ) 方法。 如果数据不是针对常见实体的,您可以创建多个不同实体的列表,并在处理完 Excel 表后启动 DB 操作。

【讨论】:

  • 是的..你说的很对。该代码正在递归调用 save,应该将其重构为调用 saveAll。但只是想知道我是否在从 EntityManager 对象创建的事务边界中递归调用相同的保存方法,这将解决“无法获取 jdbc 连接”的问题。我的问题是,当手动打开和关闭事务时,保存在该边界内的所有实体确实发生在单个连接对象上还是分布在多个连接对象上?
  • 您的问题非常有效,但即使您将在单个事务中执行整个操作,您也会多次访问数据库,并且每次您的应用程序都将使用来自连接池的新连接,并且你的情况就是这样。
猜你喜欢
  • 1970-01-01
  • 2020-04-22
  • 2018-11-17
  • 2020-08-30
  • 1970-01-01
  • 1970-01-01
  • 2018-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多