我在 Spring-boot 项目中使用 Spring JPA。我有一个简单的命名查询。该过程每 10 秒调用一次。如果没有在我的存储库接口(interface)上注释@Transactional,连接池中的连接就会耗尽。我收到“超时:池为空。无法在 30 秒内获取连接,没有可用的连接[大小:100;繁忙:100;空闲:0;lastwait:30000]。”
但是,在我添加@Transactional注释之后,它工作得很好。注释和释放回池的连接之间有什么关系?我以为Spring JPA会在方法调用完成后自动释放连接。
@Repository
@Transactional
public interface StoredProcedureRepository extends CrudRepository<StoredProcedureDO, Long> {
@Procedure(name = "invokeStoredProc")
void invokeStoredProc(@Param("id") Long id, @Param("date") java.sql.Date date);
}
@Entity
@NamedStoredProcedureQuery(name ="invokeStoredProc",
procedureName = "schema.storedProc",
parameters = {
@StoredProcedureParameter(mode = ParameterMode.IN, name = "id", type = Long.class),
@StoredProcedureParameter(mode = ParameterMode.IN, name = "date", type = java.sql.Date.class)})
public class StoredProcedureDO implements Serializable {
最佳答案
我的项目中也遇到了类似的问题。我使用的是OracleDB+Springboot+hikari+hibernate。花了很多时间调试问题,最后发现原因是我的线程即使在执行DB操作后也没有保持连接直到线程退出。
在一个请求中,我有 3 个不同的数据库调用,中间有 2 个远程调用。如果我的远程调用需要一些时间才能返回,则线程会保持数据库连接,即使它没有在数据库上操作。这会导致其他线程挨饿并耗尽我的 API 性能,从而导致超时。
我发现下面的文章建议使用
spring.jpa.open-in-view=false
https://raul8804.wordpress.com/2019/03/31/spring-boot-project-db-connection-leak-investigation/
添加此配置后,我看到连接正在被获取并返回到池中,然后再进行数据库调用并返回。之后,我几乎没有看到来自 Hikari 调试日志的 3 个 Activity 连接,用于之前失败的相同负载。
关于java - 为什么我的数据库连接在没有 @Transactional 的情况下会泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52337384/