Spring Примеры использования пула соединений JDBC
У меня есть базовое приложение Spring JDBC с довольно простой конфигурацией:
<bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@1.1.1.1:1521:XXX"/>
<property name="username" value="username"/>
<property name="password" value="password"/>
</bean>
<bean id="dbThing" class="com.DbThing">
<property name="dataSource" ref="myDataSource"/>
</bean>
Я хотел бы представить пул соединений и после прочтения нескольких потоков здесь на SO Я немного запутался в том, какую библиотеку пула использовать.
Библиотеки, которые, похоже, имеют больше кредитов на SO, CP30 и DBCP. Поскольку я использую Oracle, я мог бы также использовать пул данных источника, предлагаемый драйвером.
Я понимаю, что доступно больше библиотек - например, новые библиотеки пула Apache Tomcat 7.
Есть ли какая-нибудь библиотека, которую я должен действительно избегать?
Есть ли рекомендуемая конфигурация, которую я должен использовать с данной библиотекой?
Любая "военная история", которую вы хотите поделиться?
Ответы
Ответ 1
C3PO и разработка DBCP зашли в тупик главным образом потому, что они зрелые. Я видел, что оба этих драйвера могут поддерживать сотни транзакций в секунду.
Пул Tomcat - это переработанный и обновленный драйвер DBCP. MyBatis 3.0 также содержит собственную реализацию объединения, которая, основываясь на проверке кода, кажется солидной. Наконец, BoneCP, который утверждает, что имеет лучшую производительность. Я еще не использовал ни одного из них в проекте.
Наверное, лучшим советом является выбор любого из них. Spring упрощает замену позже.
Ответ 2
Как альтернатива BoneCP, возможно, вы попробовали собственный пул соединений с базой данных Oracle?
У меня были хорошие впечатления в течение последних двух недель, так что, возможно, стоит потратить на это выстрел. Кроме того, я полагаю, что Oracle узнает кое-что о создании пула подключений, особенно когда в паре с их собственной базой данных.
<bean id="dataSource" class="oracle.jdbc.pool.OracleConnectionPoolDataSource">
<property name="URL" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
UPDATE. Кроме того, если вы используете (один из) новейших драйверов JDBC Oracle (11.2.0.1+), вы можете попробовать новый универсальный пул соединений. OracleConnectionPoolDataSource
, похоже, официально устарел в пользу этого пула. Однако некоторые пользователи сообщают об ошибках, используя это, поэтому может быть слишком рано. Я в состоянии использовать последние JDBC-драйверы Oracle, поэтому я дам ему попробовать и обновить здесь, как только у вас есть информация об этом.
Дополнительная информация по этой теме: Oracle UCP
Ответ 3
BoneCP
, но затем вводится новый инструмент с именем HiKariCP
, он преодолел множество недостатков, которые присутствовали в инструментах прохода, которые вы можете настроить с помощью изменения ниже application-context.xml
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="maximumPoolSize" value="10" />
<property name="minimumPoolSize" value="2" />
<property name="dataSourceClassName"
value="oracle.jdbc.pool.OracleDataSource" />
<property name="dataSourceProperties" ref="props" />
<property name="poolName" value="springHikariCP" />
</bean>
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<constructor-arg ref="hikariConfig" />
</bean>
<util:properties id="props" location="classpath:datasource.properties"/>
где в database.properties
вы должны предоставить подробную информацию о базе данных, как показано ниже
url=jdbc:oracle:thin:@IP:port:SID/Databasename
user=usernmae
password=password
Для правильной демонстрации вы можете использовать эту ссылку
Ответ 4
Определенно вы можете использовать C3P0, это разработано для корпоративного решения. Чтобы проверить преимущества, вы можете следовать этому ответу.
Вот пример кода интеграции:
@Bean
public JpaTransactionManager transactionManager() {
JpaTransactionManager transactionManager =
new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
Этот JpaTransactionManager
предназначен для получения JpaTransactionManager
.
@Primary
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
entityManagerFactoryBean.setPackagesToScan("YOUR.DATABSE.ENTITY.PACKAGE");
entityManagerFactoryBean.setJpaProperties(hibProperties());
return entityManagerFactoryBean;
}
Этот бит предназначен для получения LocalContainerEntityManagerFactoryBean
. Он принимает DataSource
, PersistenceProviderClass
, Entity Имя пакета PackagesToScan
и JpaProperties от hibProperties()
.
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
return properties;
}
Здесь env value are comming from application.properties
.
Проверить свойства:
hibernate.dialect: org.hibernate.dialect.Oracle12cDialect
hibernate.show_sql: false
hibernate.hbm2ddl.auto: none
Основная часть - DataSource Setup. Это дано ниже:
@Bean
public ComboPooledDataSource dataSource(){
ComboPooledDataSource dataSource = new ComboPooledDataSource();
try {
dataSource.setDriverClass(env.getProperty("db.driver"));
dataSource.setJdbcUrl(env.getProperty("db.url"));
dataSource.setUser(env.getProperty("db.username"));
dataSource.setPassword(env.getProperty("db.password"));
dataSource.setMinPoolSize(Integer.parseInt(env.getProperty("minPoolSize")));
dataSource.setMaxPoolSize(Integer.parseInt(env.getProperty("maxPoolSize")));
dataSource.setMaxIdleTime(Integer.parseInt(env.getProperty("maxIdleTime")));
dataSource.setMaxStatements(Integer.parseInt(env.getProperty("maxStatements")));
dataSource.setMaxStatementsPerConnection(Integer.parseInt(env.getProperty("maxStatementsPerConnection")));
dataSource.setMaxIdleTimeExcessConnections(10000);
} catch (PropertyVetoException e) {
e.printStackTrace();
}
return dataSource;
}
Он использует ComboPooledDataSource
который использует гораздо более важные параметры, такие как maxPoolSize, MinPoolSize, MaxIdleSize и т.д. Этот параметр среды приведен ниже:
db.driver: oracle.jdbc.driver.OracleDriver // for Oracle
db.username: YOUR_USER_NAME
db.password: YOUR_USER_PASSWORD
db.url: DATABASE_URL
minPoolSize:5 // number of minimum poolSize
maxPoolSize:100 // number of maximum poolSize
maxIdleTime:5 // In seconds. After that time it will realease the unused connection.
maxStatements:1000
maxStatementsPerConnection:100
maxIdleTimeExcessConnections:10000
Вот полный рабочий пример кода:
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.*;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
import java.util.Properties;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories
@PropertySource("classpath:application.properties")
@Scope("singleton")
public class TestDataSource {
@Autowired
private Environment env;
@Qualifier("dataSource")
@Autowired
private DataSource dataSource;
@Bean
public JpaTransactionManager transactionManager() {
JpaTransactionManager transactionManager =
new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
@Primary
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
entityManagerFactoryBean.setPackagesToScan("YOUR.PACKAGE.NAME");
entityManagerFactoryBean.setJpaProperties(hibProperties());
return entityManagerFactoryBean;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
@Bean
public ComboPooledDataSource dataSource(){
ComboPooledDataSource dataSource = new ComboPooledDataSource();
try {
dataSource.setDriverClass(env.getProperty("db.driver"));
dataSource.setJdbcUrl(env.getProperty("db.url"));
dataSource.setUser(env.getProperty("db.username"));
dataSource.setPassword(env.getProperty("db.password"));
dataSource.setMinPoolSize(Integer.parseInt(env.getProperty("minPoolSize")));
dataSource.setMaxPoolSize(Integer.parseInt(env.getProperty("maxPoolSize")));
dataSource.setMaxIdleTime(Integer.parseInt(env.getProperty("maxIdleTime")));
dataSource.setMaxStatements(Integer.parseInt(env.getProperty("maxStatements")));
dataSource.setMaxStatementsPerConnection(Integer.parseInt(env.getProperty("maxStatementsPerConnection")));
dataSource.setMaxIdleTimeExcessConnections(10000);
} catch (PropertyVetoException e) {
e.printStackTrace();
}
return dataSource;
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
return properties;
}
}
Другое дело. Вот ссылка градиента
compile group: 'org.hibernate', name: 'hibernate-c3p0', version: '5.2.10.Final'
Надеюсь, что это поможет вам. Благодаря :)