Hibernate: конфигурация пула C3p0 замедляет весь сервер.
Я работаю над приложением Spring-MVC, в котором мы используем Hibernate и c3p0 для транзакций базы данных и пула соединений. Большую часть времени это работает действительно хорошо, никаких проблем. Но в определенных ситуациях мне приходится копировать много объектов и файлов в текущей транзакции. Когда это происходит, весь сервер замедляется, и, наконец, я начинаю получать could not rollback exception
, Что-то не так с моими настройками c3p0? Спасибо.
pom.xml:
<!--- Hibernate dependencies -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>4.3.9.Final</version>
</dependency>
root-context.xml:
<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<beans:property name="driverClassName" value="org.postgresql.Driver"/>
<beans:property name="url"
value="jdbc:postgresql://localhost:PORT/DB_NAME"/>
<beans:property name="username" value="USERNAME"/>
<beans:property name="password" value="PASSWORD"/>
<beans:property name="removeAbandoned" value="true"/>
<beans:property name="removeAbandonedTimeout" value="20"/>
<beans:property name="defaultAutoCommit" value="false"/>
</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">1000</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:prop key="hibernate.c3p0.min_size">1</beans:prop>
<beans:prop key="hibernate.c3p0.max_size">750</beans:prop>
<beans:prop key="hibernate.c3p0.acquire_increment">1</beans:prop>
<beans:prop key="hibernate.c3p0.idle_test_period">1000</beans:prop>
<beans:prop key="hibernate.c3p0.max_statements">150</beans:prop>
<beans:prop key="hibernate.c3p0.timeout">1200</beans:prop>
<beans:prop key="hibernate.connection.release_mode">auto</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
Спасибо.
1 ответ
Для начала вы не используете C3P0 просто потому, что вы настроили org.apache.commons.dbcp.BasicDataSource
как DataSource
и вводят это в ваш LocalSessionFactoryBean
, Это в основном делает все hibernate.c3p0
Настройки бесполезны, так как они будут игнорироваться.
Далее у вас есть проблемы с обработкой больших объемов данных, и я очень сомневаюсь, что проблема заключается в вашей DataSource
или пул соединений, а не то, как вы обрабатываете свои сущности и как вы настроили Hibernate.
Для ускорения пакетной обработки вы хотите сбросить все x записей в базу данных и очистить кэш первого уровня. Почему вы хотите сделать это, вы можете спросить. Все это связано с тем, как работает Hibernate: когда вы сохраняете сущность, то, что делает Hibernate, она добавляет ее в кэш первого уровня (Session
или же EntityManager
в случае JPA). Каждый раз, когда вы добавляете элемент в кеш первого уровня, он выполняет грязную проверку ВСЕХ сущностей в кеше первого уровня, чтобы определить, нужно ли что-то очищать. Теперь это будет быстро для первых нескольких объектов, но будет становиться все медленнее и медленнее.
Давайте настроим и закодируем вещи для размера пакета 50.
Сначала вы хотите настроить hibernate на правильный размер пакета и упорядочить операторы вставки и обновления. Если вы сделаете это, вы сможете извлечь выгоду из того факта, что JDBC теперь может выполнять пакетное обновление (т.е. один оператор вставки или обновления для изменения 50 записей вместо 50 отдельных операторов вставки / обновления).
Конфигурация гибернации
<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">1000</beans:prop>-->
<beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
<beans:prop key="hibernate.cache.use_second_level_cache">true</beans:prop>
<beans:prop key="hibernate.cache.use_query_cache">true</beans:prop>
<beans:prop key="hibernate.jdbc.batch_size">50</beans:prop>
<beans:prop key="hibernate.order_inserts">true</beans:prop>
<beans:prop key="hibernate.order_updates">true</beans:prop>
<!-- If you use versioned entities set this to true as well -->
<beans:prop key="hibernate.jdbc.batch_versioned_data">true<beans:prop>
</beans:props>
</beans:property>
</beans:bean>
Модификация кода
public void yourLargeDataSetProcessingMethod() {
Session session = sessionFactory.getCurrentSession();
int i = 0;
for (YourItem item : List<YourItem> items) {
i++:
// Here will be processing / creation
if (i % 50 == 0) {
session.flush();
session.clear();
}
}
session.flush();
session.clear();
}
Это, вероятно, ускорит вашу обработку и блокировку базы данных.
В заключение, вместо Commons DBCP или C3P0 я бы предложил использовать HikariCP в качестве пула соединений. Он очень маленький, очень быстрый и активно поддерживается (тогда как C3P0 уже давно не используется).
Вот хороший ресурс (с тестами и т. Д.) О том, что делает каждый параметр, а также о том, как добавлять или удалять производительность, и о том, как правильно настраивать параметры.