我正在使用Spring-MVC应用程序,我们正在使用HikariCP。我们使用PostgreSQL作为数据库,在PostgreSQL中有150个连接,Hikari有15个池大小。有时,我们突然发现超时发生的错误。错误在10-20秒内消失,但它会降低整个服务器的速度。很多时候它甚至都不忙。我尝试了一些其他线程并添加了泄漏检测,但没有帮助。我有什么想法或者如何解决这个问题?
错误日志:
java.sql.SQLTimeoutException: Timeout after 30000ms of waiting for a connection.
at com.zaxxer.hikari.pool.BaseHikariPool.getConnection(BaseHikariPool.java:233)
at com.zaxxer.hikari.pool.BaseHikariPool.getConnection(BaseHikariPool.java:183)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:110)
root-context.xml:
<beans:bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<beans:property name="dataSourceClassName" value="org.postgresql.ds.PGSimpleDataSource"/>
<beans:property name="minimumIdle" value="2"/>
<beans:property name="maximumPoolSize" value="17" />
<beans:property name="maxLifetime" value="300000" />
<beans:property name="idleTimeout" value="25000" />
<beans:property name="leakDetectionThreshold" value="3000"/>
<beans:property name="dataSourceProperties">
<beans:props>
<beans:prop key="url">jdbc:postgresql://localhost:5432/DB_NAME</beans:prop>
<beans:prop key="user">USERnamE</beans:prop>
<beans:prop key="password">PASSWORD</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<!-- Hibernate 4 SessionFactory Bean definition -->
<beans:bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource"/>
<beans:property name="packagesToScan" value="com.ourapp.spring.model"/>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL9Dialect</beans:prop>
<beans:prop key="hibernate.show_sql">false</beans:prop>
<beans:prop key="hibernate.jdbc.batch_size">50</beans:prop>
<beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
<beans:prop key="cache.use_second_level_cache">true</beans:prop>
<beans:prop key="cache.use_query_cache">true</beans:prop>
<beans:prop key="hibernate.order_updates">true</beans:prop>
<beans:prop key="show_sql">false</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
任何帮助都会很好。谢谢。 : - )
更新
典型的保存和阅读:
@Repository
@Transactional
public class AppDetailsDAOImpl implements AppDetailsDAO {
private final SessionFactory sessionFactory;
@Autowired
public AppDetailsDAOImpl(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public Long saveAppDetails(AppDetails appDetails, int personid) {
Session session = this.sessionFactory.getCurrentSession();
Person person = (Person) session.get(Person.class, personid);
if (person != null) {
person.getAppDetailsSet().add(appDetails);
appDetails.setUserApps(person);
Long saveid = (Long) session.save(appDetails);
session.flush();
return saveid;
}
return (long) 0;
}
@Override
public AppDetails getAppDetailsByAppId(Long appId) {
Session session = this.sessionFactory.getCurrentSession();
return (AppDetails) session.get(AppDetails.class, appId);
}
}
答案 0 :(得分:1)
由于您的应用程序业务逻辑,您的连接用尽。就像你说的那样:
问题是我主要是短期运行事务,很少有长时间运行事务
不是为短期运行事务增加池大小而是为长时间运行的事务声明一个单独的新DataSource
bean。新的DataSource
应该由新的HikariCP池支持。它甚至可以具有0的最小大小,因为如果运行长时间运行的事务,建立新数据库连接的成本应该是无关紧要的,例如月报。
分离OLTP和OLAP处理是正确的方法,例如见CQRS。例如,您可以每天刷新一个单独的OLAP数据库来处理报告,而主OLTP数据库不受耗时的报告工作负载的影响。
答案 1 :(得分:-1)
更改Postgres驱动程序并更改hikaricp的设置
spring.datasource.hikari.minimumIdle=5
spring.datasource.hikari.maximumPoolSize=20
spring.datasource.hikari.idleTimeout=30000
spring.datasource.hikari.poolName=SpringBootJPAHikariCP
spring.datasource.hikari.maxLifetime=2000000
spring.datasource.hikari.connectionTimeout=30000
spring.jpa.hibernate.connection.provider_class=org.hibernate.hikaricp.internal
.HikariCPConnectionProvider