【问题标题】:Why is my DB connection leaking without @Transactional?为什么我的数据库连接在没有@Transactional 的情况下泄漏?
【发布时间】:2019-02-19 14:04:26
【问题描述】:

我在 Spring-boot 项目中使用 Spring JPA。我有一个简单的命名查询。 proc 每 10 秒调用一次。如果没有在我的存储库接口上注释 @Transactional,连接池中的连接就会耗尽。我得到“超时:池为空。无法在 30 秒内获取连接,无可用 [大小:100;忙:100;空闲:0;最后等待: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 {

【问题讨论】:

  • 您使用的是哪个连接池?
  • 我没有在属性文件中指定任何内容。我假设 Spring 使用的是默认值。从调用堆栈中,我可以看到它正在使用 Tomcat 连接池。
  • 如何调用 invokeStoresProc ?通过计划任务?
  • 连接释放方式呢?
  • 连接释放方式呢?

标签: java spring spring-boot jpa spring-data-jpa


【解决方案1】:

我在我的项目中遇到了类似的问题。我使用的是 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 个活动连接,它们与之前失败的负载相同。

【讨论】:

    猜你喜欢
    • 2016-07-13
    • 2023-01-16
    • 2012-07-11
    • 1970-01-01
    • 1970-01-01
    • 2021-02-21
    • 2016-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多