Я использую спящий режим, чтобы попытаться получить кешированный запрос.
@Transactional
public interface ProductDAO extends JpaRepository<Product, Long> {
@QueryHints({ @QueryHint(name = "org.hibernate.cacheable", value = "true") })
Product findByCode(String code);
}
Я тестирую нагрузку и делаю это в большом цикле из 1000 итераций.
for (int i = 0; i < 500; i++) {
URL myURL = new URL("http://localhost:8080/test");
URLConnection myURLConnection = myURL.openConnection();
myURLConnection.connect();
myURLConnection.getContent();
}
Я проверил с помощью showql и вижу, что при первом обращении к БД создается только 1 оператор SQL, после чего он кэшируется.
Тем не менее, я все еще получаю следующую ошибку, хотя SQL не отображается:
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Too many connections
Мои свойства Hibernate:
#hibernate properties
hibernate.dialect = ${hibernate.dialect}
hibernate.show_sql = false
hibernate.hbm2ddl.auto = ${hibernate.hbm2ddl}
hibernate.c3p0.min_size = 10
hibernate.c3p0.max_size = 100
hibernate.c3p0.timeout = 300
hibernate.c3p0.max_statements = 50
hibernate.c3p0.acquire_increment = 5
hibernate.c3p0.idle_test_period = 3000
hibernate.cache.use_second_level_cache=true
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
hibernate.cache.use_query_cache=true
Конфигурация базы данных:
<bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="${db.url}" />
<property name="driverClassName" value="${db.driverClassName}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="${hibernate.dialect}" />
</bean>
</property>
<property name="jpaProperties" ref="hibernateProperties" />
<property name="packagesToScan">
<array>
<value>com.exammple.model</value>
</array>
</property>
</bean>
<bean id="hibernateProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:/spring/hibernate.properties" />
</bean>
<bean id="sessionFactory" factory-bean="entityManagerFactory" factory-method="getSessionFactory" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="dataSource" ref="dataSource" />
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<jpa:repositories base-package="com.example.dal" entity-manager-factory-ref="entityManagerFactory"
transaction-manager-ref="transactionManager" repository-impl-postfix="CustomImpl" />
2 ответа
Проблема в вашей конфигурации: вы не используете пул соединений.
Вы настраиваете DriverManagerDataSource
, который не является правильным пулом соединений. Вы вводите этот компонент в LocalContainerEntityManagerFactoryBean
, что делает ваши свойства hibernate.connection
и hibernate.c3p0
бесполезными, они не используются.
Решение довольно простое: отбросьте свойства hibernate.c3p0
и hibernate.connection
и замените DriverManagerDataSource
правильной реализацией пула. Я бы порекомендовал HikariCP вместо C3P0, но это личное предпочтение.
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="poolName" value="springHikariCP" />
<property name="connectionTestQuery" value="SELECT 1" />
<property name="dataSourceClassName" value="${db.driverClassName}" />
<property name="dataSourceProperties">
<props>
<prop key="url">${db.url}</prop>
<prop key="user">${db.username}</prop>
<prop key="password">${jdb.password}</prop>
</props>
</property>
</bean>
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<constructor-arg ref="hikariConfig" />
</bean>
У этой проблемы может быть несколько проблем:
Вы не закрываете соединения с базой данных.
Вы устанавливаете максимальный пул соединений размер пула, который превышает максимально допустимое количество подключений ваш сервер базы данных. Когда количество клиентов превышает максимально допустимое количество подключений, возникает подобное исключение.
Я мог бы использовать FlexyPool, чтобы отслеживать использование пула соединений и выяснять, не протекают ли соединения или нет. сдаются в долгосрочную аренду.
Обновить
Как уже сказал М. Дейнум, вы не используете пул соединений.
Вы все еще можете использовать свойства Hibernate C3P0, но вам нужно удалить dataSource
из LocalContainerEntityManagerFactoryBean
:
<property name="dataSource" ref="dataSource" />
Таким образом, Hibernate может использовать свойства hibernate.c3p0
.
Похожие вопросы
Новые вопросы
java
Java — это высокоуровневый объектно-ориентированный язык программирования. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег часто используется вместе с другими тегами для библиотек и/или фреймворков, используемых разработчиками Java.