我有一个Spring Boot
(1.5.3)应用程序,Hibernate
(5.0.12) SessionFactory
如下所示:
在application.properties
中
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
在配置类中:
@Bean
public HibernateJpaSessionFactoryBean sessionFactory() {
return new HibernateJpaSessionFactoryBean();
}
在@Services
中
@Autowired
private SessionFactory sessionFactory;
这个效果很好。但是,我的问题是,在每次请求之后,我得到越来越多空闲的PostgreSQL
进程,并且在多次请求之后,我最终得到了以下内容:
Caused by: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
...
Caused by: org.postgresql.util.PSQLException: FATAL: remaining connection slots are reserved for non-replication superuser connections
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2455) ~[postgresql-9.4.1212.jre7.jar:9.4.1212.jre7]
...
[ERROR] [16.05.17 20:19:39] DirectJDKLog.java:181 Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction;
nested exception is javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:431) ~[spring-orm-4.3.8.RELEASE.jar:4.3.8.RELEASE]
...
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
...
Caused by: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
...
Caused by: org.postgresql.util.PSQLException: FATAL: remaining connection slots are reserved for non-replication superuser connections
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2455) ~[postgresql-9.4.1212.jre7.jar:9.4.1212.jre7]
...
[ERROR] [16.05.17 20:19:39] DirectJDKLog.java:181 Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction;
nested exception is javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:431) ~[spring-orm-4.3.8.RELEASE.jar:4.3.8.RELEASE]
...
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
...
Caused by: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
...
Caused by: org.postgresql.util.PSQLException: FATAL: remaining connection slots are reserved for non-replication superuser connections
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2455) ~[postgresql-9.4.1212.jre7.jar:9.4.1212.jre7]
...
[ WARN] [16.05.17 20:19:40] SqlExceptionHelper.java:127 SQL Error: 0, SQLState: 53300
[ERROR] [16.05.17 20:19:40] SqlExceptionHelper.java:129 FATAL: remaining connection slots are reserved for non-replication superuser connections
[ERROR] [16.05.17 20:19:40] DirectJDKLog.java:181 Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed;
nested exception is org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection] with root cause
org.postgresql.util.PSQLException: FATAL: remaining connection slots are reserved for non-replication superuser connections
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2455) ~[postgresql-9.4.1212.jre7.jar:9.4.1212.jre7]
对于简单的SQL查询,我经常使用StatelessSession
,在返回结果之前,我确信在相关的@Service
中关闭它们是99.9%。
我有一种未经证实的感觉,即使用早期的Spring版本,以及提取的依赖项,这个问题并不存在。但不确定..。
这些明显泄漏的原因是什么?
为了完整起见,这里有一些示例在@Service
中使用
@Transactional(readOnly = true)
@Cacheable(value = "countries", key = "#root.methodName")
public List<Country> getCountries() {
final StatelessSession session = sessionFactory.openStatelessSession();
final Query query = session.createQuery("from Country order by id");
final List<Country> result = query.list();
session.close();
return result;
}
@Transactional(readOnly = true)
public long countTimeZones() {
final StatelessSession session = sessionFactory.openStatelessSession();
final Long result = (Long) session.createQuery("select count(o) from TimeZone o").uniqueResult();
session.close();
return result;
}
@Transactional(readOnly = true)
public List<Map<String, Object>> getPhotoAlbums() {
final StatelessSession session = sessionFactory.openStatelessSession();
final SQLQuery query = session.createSQLQuery("select "
+ "cast(m.id as varchar), "
+ "m.name "
// etc
+ "from media_album m "
+ "where m.account = :account "
+ "and ... "
+ "order by ...");
query.setParameter("account", uuidOfAccount);
query.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE);
final List<Map<String, Object>> result = query.list();
session.close();
return result;
}
发布于 2017-05-17 20:01:22
我可以通过如下更改配置来“解决”漏洞(但不确定所有这些步骤都是必要的):
application.properties:
spring.jpa.properties.hibernate.current_session_context_class=
org.springframework.orm.hibernate5.SpringSessionContext
配置类:
添加@EnableAutoConfiguration
,以及:
@Bean
public HibernateJpaSessionFactoryBean sessionFactory(EntityManagerFactory emf) {
HibernateJpaSessionFactoryBean factory = new HibernateJpaSessionFactoryBean();
factory.setEntityManagerFactory(emf);
return factory;
}
这一回答很有帮助:
required a bean of type 'org.hibernate.SessionFactory' that could not be found
发布于 2017-05-16 20:44:56
我相信您需要设置以下属性:
spring.datasource.max-active
例如spring.datasource.max-active=5
看起来,spring连接池打开的连接比postgresql.conf文件中允许的多。
https://stackoverflow.com/questions/44011060
复制相似问题