了解数据库连接池

16-11-22 banq
    

1.介绍

连接池是事先打开N个数据库连接放入池中进行管理的性能优化技术。应用程序只需要一个连接,使使用完以后将其放回池中。 当应用程序需要连接时,池中总是保持就绪可用连接。池管理连接生命周期,使得开发人员实际上不需要等待连接的建立过程并过滤掉过时的连接。

连接池机制节省了运行时创建网络连接的昂贵成本,总是在后台初始化数据库会话。

2. TOMCAT中的连接池实现

Tomcat中是领先的应用服务器,Commons DBCP数据源作为其默认的JNDI数据源,除非我们明确指定DataSourceFactory,以下是使用方式:

使用Apache Commons DBCP连接池 -

<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
	maxActive="100" maxIdle="30" maxWait="10000"
	username="javauser" password="javadude" driverClassName="com.mysql.jdbc.Driver"
	url="jdbc:mysql://localhost:3306/javatest" 
        factory="org.apache.commons.dbcp.BasicDataSourceFactory"/>
<p>

 使用 Tomcat JDBC Connection pool :


<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
	maxActive="100" maxIdle="30" maxWait="10000"
	username="javauser" password="javadude" driverClassName="com.mysql.jdbc.Driver"
	url="jdbc:mysql://localhost:3306/javatest" 
        factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"/>

<p>

factory是必需的, 类型应始终为javax.sql.DataSource

DBCP的优点是它可以与许多应用程序或框架一起使用,并且它几乎能与市场上的所有数据库一起工作。

3.比较连接池机制

当使用Commons DBCP连接池机制,Tomcat获取Commons DBCP源(版本取决于Tomcat的版本,例如Tomcat的7.0.27使用Commons DBCP 1.4),并执行包的名称替换(org.apache.commons - > org.apache.tomcat.dbcp)并构建成Tomcat-dbcp.jar。 这样做是为了使内部Tomcat JDBC池不会与Commons DBCP类的应用程序使用发生冲突。 这避免了许多潜在的类加载问题。“dbcp”包是关于数据源管理的。

同样,Tomcat的JDBC连接池机制(org.apache.tomcat.jdbc.pool.*)是与Commons DBCP数据库连接池竞争的替代升级实现。 它是一个Tomcat分离出单独的项目(在Tomcat模块 - > jdbc-pool),它首次配置于Tomcat 7(2011年7月7.0.19开始)。这两个实现都有优点和缺点,然而Apache Commons DBCP仍然被更普遍使用。

在这两种情况下,相应的JAR文件( commons-dbcp.jar 或 tomcat-jdbc.jar)都需要被纳入构建路径。

旧版本的Apache Commons DBCP(即版本1.2)在高负载条件下有一些讨厌的线程安全问题,使得它不适合被再使用,这就是为什么重写Tomcat JDBC连接池原因。

使用Tomcat JDBC连接池也很简单,对于已经熟悉DBCP的人来说,转换也是相当简单的。

4.在HIBERNATE中的连接池

Hibernate使用它的魔法来标识要使用的连接池提供程序 - 基于您配置的属性。

对于c3p0 -

<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
<p>

对于Apache Commons DBCP -

<property name="hibernate.dbcp.initialSize">8</property>
<property name="hibernate.dbcp.maxActive">20</property>
<property name="hibernate.dbcp.maxIdle">20</property>
<property name="hibernate.dbcp.minIdle">0</property>
<p>

相应的JAR文件需要位于lib目录中,手动配置或使用Maven。

我们也可以使用hibernate.connection.provider_class属性显式指定连接提供者,但其并不真正需要。

<property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.max_size">19</property>
<property name="hibernate.c3p0.timeout">120</property>
<property name="hibernate.c3p0.max_statements">10</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
<p>

如果我们不配置与Hibernate连接池,则使用默认的,当我们启动应用程序,在日志或控制台输出中可见-

org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure

Hibernate中默认的连接池实现不适合生产使用,因为它的配置限制了。如果您使用应用程序服务器,则可能希望使用内置池(通常使用JNDI获取连接)。

使用JNDI配置让Hibernate使用服务器的内置池,我们需要将以下属性设置到Hibernate配置文件中 -

hibernate.connection.datasource=java:/comp/env/jdbc/TestDB

- 假设TestDB是Tomcat JDBC连接池DataSource的JNDI名称(参考上面第2节中的代码片段)。

如果您不能或不希望使用应用程序服务器的内置连接池,Hibernate支持其他几个连接池,例如 -

c3p0

Proxool

Apache的DBCP之后,C3P0是第二个最好的连接池的实现,容易与Hibernate集成,据说能够提供良好的性能。

Understanding Connection Pooling - jCombat