Spring Data DB连接管理

时间:2016-08-27 15:05:43

标签: spring spring-data

如果我调用Spring Repository方法来查询数据库,那么Spring何时会释放连接?

我问,因为我有一个方法可以进行同步HTTP调用以及调用Spring Repository方法。当我呼叫的服务失败时,由于超时,我开始在日志中看到以下内容:

  

PoolExhaustedException:[http-nio-8080-exec-47]超时:池为空。无法在30秒内获取连接,无法使用[size:15;忙碌:15;空闲:0; lastwait:30000]

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

2 个答案:

答案 0 :(得分:0)

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

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)

所以似乎释放连接的方法是DataSourceUtils#releaseConnection。如果您想知道连接发生了什么,您应该至少启用此类的日志记录。

另一方面,我认为这是预期的行为。您有一个长时间运行的方法,它是以事务方式执行的,所以它可以在失败时回滚,但是每次执行时代码都会获取连接。为了解决您的问题,您可以尝试为您的方法优化代码根本不使其成为交易,或者您可以增加最大连接数量< / strong>用于连接池。

答案 1 :(得分:0)

我有完全相同的问题。我试图释放与DataSourceUtils#releaseConnection的连接,但是它确定连接没有在连接池中结束,因为连接持有者不是容器而不是&#34;我&#34;

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