Spring 正在返回的存储库方法 Java 8 流未关闭 JDBC 连接

Spring repository method which are returning Java 8 stream doesn't close JDBC connection

我有一个 Spring data 存储库:

@Repository
interface SomeRepository extends CrudRepository<Entity, Long> {
    Stream<Entity> streamBySmth(String userId);
}

我正在某些 Spring bean 中调用该方法:

@Scheduled(fixedRate = 10000)
private void someMethod(){
    someRepository.streamBySmth("smth").forEach(this::callSomeMethod);
}

我正在使用 MySQL 数据库。当我在一些成功的方法调用后 运行 应用程序时,它抛出一个异常:

o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: 08001
o.h.engine.jdbc.spi.SqlExceptionHelper   : Could not create connection to database server.
o.s.s.s.TaskUtils$LoggingErrorHandler    : Unexpected error occurred in scheduled task.

org.springframework.dao.DataAccessResourceFailureException: Unable to acquire JDBC Connection; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection

似乎 Spring 没有正确关闭该连接。如果我将方法 return 的值从 Stream 更改为 List,它可以正常工作。

更新: Spring引导版本为1.4。1.RELEASE

由于 reference documentation clearly statesStreams 需要与 try-with-resources 块一起使用。

此外,通过使用 @Transactional 注释周围的方法,确保在使用流时保持(只读)事务处于打开状态。否则将应用默认设置并尝试在存储库方法 return.

上释放资源
@Transactional
public void someMethod() {

  try (Stream<User> stream = repository.findAllByCustomQueryAndStream()) {
    stream.forEach(…);
  } 
}

使用@Transactional(readOnly = true) 和public 访问修饰符将解决问题。任何其他访问修饰符都不起作用。