为什么没有@Transactional的情况下我的数据库连接会泄漏?

时间:2018-09-14 18:19:55

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

我在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 {

1 个答案:

答案 0 :(得分:0)

我的项目中有类似的问题。我正在使用OracleDB + Springboot + hikari + hibernate。花了很多时间来调试问题,最后发现原因是我的线程直到执行完数据库操作后才退出线程,直到线程退出为止。

在一个请求中,我有3个不同的DB调用,中间有2个远程调用。如果我的远程调用花时间返回,即使线程不在数据库上运行,线程也会保持数据库连接。这导致其他线程饿死,并耗尽了我的API性能,导致超时。

我发现下面的文章建议使用

spring.jpa.open-in-view = false

https://raul8804.wordpress.com/2019/03/31/spring-boot-project-db-connection-leak-investigation/

添加此配置后,我看到正在建立连接并从数据库调用返回之前,连接已经建立并返回到池中。此后,我几乎看不到来自Hikari调试日志的3个活动连接,且连接失败了。