Spring数据数据库连接管理

Spring数据数据库连接管理,spring,spring-data,Spring,Spring Data,如果我调用Spring存储库方法来查询DB,Spring何时释放连接 我之所以这么问,是因为我有一个方法可以在调用Spring存储库方法的同时进行同步HTTP调用。当我调用的服务由于超时而失败时,我开始在日志中看到以下内容: PoolDesustedException:[http-nio-8080-exec-47]超时:池为空。无法在30秒内获取连接,没有可用的连接[size:15;busy:15;idle:0;lastwait:30000] 我假设这是因为在方法完成之前连接不会释放回池,但我无

如果我调用Spring存储库方法来查询DB,Spring何时释放连接

我之所以这么问,是因为我有一个方法可以在调用Spring存储库方法的同时进行同步HTTP调用。当我调用的服务由于超时而失败时,我开始在日志中看到以下内容:

PoolDesustedException:[http-nio-8080-exec-47]超时:池为空。无法在30秒内获取连接,没有可用的连接[size:15;busy:15;idle:0;lastwait:30000]


我假设这是因为在方法完成之前连接不会释放回池,但我无法找到和说明连接管理机制的文档。

默认情况下,事务完成时连接关闭,至少如果您使用声明性事务并让Spring自己管理它们。在中,有一个声明性事务实现的示例:

public final class Boot {

    public static void main(final String[] args) throws Exception {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("context.xml", Boot.class);
        FooService fooService = (FooService) ctx.getBean("fooService");
        fooService.insertFoo (new Foo());
    }
}
这就是您得到的输出:

<!-- the Spring container is starting up... -->
[AspectJInvocationContextExposingAdvisorAutoProxyCreator] - Creating implicit proxy for bean 'fooService' with 0 common interceptors and 1 specific interceptors

<!-- the DefaultFooService is actually proxied -->
[JdkDynamicAopProxy] - Creating JDK dynamic proxy for [x.y.service.DefaultFooService]

<!-- ... the insertFoo(..) method is now being invoked on the proxy -->
[TransactionInterceptor] - Getting transaction for x.y.service.FooService.insertFoo

<!-- the transactional advice kicks in here... -->
[DataSourceTransactionManager] - Creating new transaction with name [x.y.service.FooService.insertFoo]
[DataSourceTransactionManager] - Acquired Connection [org.apache.commons.dbcp.PoolableConnection@a53de4] for JDBC transaction

<!-- the insertFoo(..) method from DefaultFooService throws an exception... -->
[RuleBasedTransactionAttribute] - Applying rules to determine whether transaction should rollback on java.lang.UnsupportedOperationException
[TransactionInterceptor] - Invoking rollback for transaction on x.y.service.FooService.insertFoo due to throwable [java.lang.UnsupportedOperationException]

<!-- and the transaction is rolled back (by default, RuntimeException instances cause rollback) -->
[DataSourceTransactionManager] - Rolling back JDBC transaction on Connection [org.apache.commons.dbcp.PoolableConnection@a53de4]
[DataSourceTransactionManager] - Releasing JDBC Connection after transaction
[DataSourceUtils] - Returning JDBC Connection to DataSource

Exception in thread "main" java.lang.UnsupportedOperationException at x.y.service.DefaultFooService.insertFoo(DefaultFooService.java:14)
<!-- AOP infrastructure stack trace elements removed for clarity -->
at $Proxy0.insertFoo(Unknown Source)
at Boot.main(Boot.java:11)

[AspectJinSocationContextExposingAdvisorAutoProxyCreator]-使用0个公共拦截器和1个特定拦截器为bean“fooService”创建隐式代理
[JDKDDynamicAOPProxy]-为[x.y.service.DefaultFooService]创建JDK动态代理
[TransactionInterceptor]-获取x.y.service.FooService.insertFoo的事务
[DataSourceTransactionManager]-创建名为[x.y.service.FooService.insertFoo]的新事务
[DataSourceTransactionManager]-获取的连接[org.apache.commons.dbcp。PoolableConnection@a53de4]对于JDBC事务
[RuleBasedTransactionAttribute]-应用规则确定事务是否应在java.lang.UnsupportedOperationException上回滚
[TransactionInterceptor]-由于throwable[java.lang.UnsupportedOperationException]而调用x.y.service.FooService.insertFoo上事务的回滚
[DataSourceTransactionManager]-在连接[org.apache.commons.dbcp]上回滚JDBC事务。PoolableConnection@a53de4]
[DataSourceTransactionManager]-在事务完成后释放JDBC连接
[DataSourceUtils]-返回到数据源的JDBC连接
线程“main”java.lang.UnsupportedOperationException在x.y.service.DefaultFooService.insertFoo处出现异常(DefaultFooService.java:14)
位于$Proxy0.insertFoo(未知来源)
在Boot.main(Boot.java:11)
因此,似乎释放连接的方法是。如果您想知道连接发生了什么,至少应该启用此类的日志记录


从另一方面来说,我认为这是预期的行为。您有一个以事务方式执行的长时间运行的方法,因此在失败时可以回滚,但您的代码在每次执行它时都会获取一个连接。为了解决您的问题,您可以尝试为您的方法优化代码完全不使其成为事务性的,或者为您的连接池增加最大连接量。

我也有同样的问题。我试图释放与DataSourceUtils#releaseConnection的连接,但发现连接没有在连接池中结束,因为连接持有者是容器而不是“我”

我使用wsa的解决方案只是为了增加yml文件中的maxPoolSize并在控制器中缓存http请求,但仍然希望能够释放连接