数据库连接池c3p0和dbcp和tomcat-dbcp
来源:互联网 发布:清朗网络 青年力量海报 编辑:程序博客网 时间:2024/05/17 03:53
jdbc(Java DataBase Connection):
是应用程序与数据库沟通的桥梁, 即Java语言通过JDBC技术访问数据库。
一般来说,Java应用程序访问数据库的过程是:
①装载数据库驱动程序;
②通过JDBC建立数据库连接;
③访问数据库,执行SQL语句;
④断开数据库连接。
jdbc是一种数据库访问技术,具有简单易用的优点。但在WEB应用程序开发中,存在很多问题:
首先、每一次WEB请求都要建立一次数据库连接,建立连接是个费时的活动,而且过程中系统还要分配内存资源。在高并发情况下,这种频繁的对数据库连接操作势必会降低响应速度,严重的可能导致服务器崩溃;
其次,对于每次的数据库连接,使用完都得断开,如若连接未能关闭,将会导致数据库系统内存泄漏。最终将不得不重启数据库。
再者,这种连接方式不能控制被创建的连接数,会将系统资源毫无保留的分配出去,连接数过多,也会导致内存泄漏,导致服务器崩溃。
由上面的分析可以看出,问题就出在对数据库资源连接的低效管理。由此,我们在此基础上对JDBC进行优化,提出了数据库连接池(connection pool)。
资源池(resoure pool)主要作用有俩个:控制数量、资源重利用。
连接池的分配与释放:
已经创建的连接都放入List中去统一管理。每当用户请求一个连接时,系统检查这个List中有没有可以分配的连接。如果有就把那个最合适的连接分配给他;如果没有就抛出一个异常给用户,List中连接是否可以被分配由一个线程来专门管理。
连接池的配置与维护:
采取设置最小连接数(minConnection)和最大连接数(maxConnection)等参数来控制连接池中的连接,来使系统的性能最佳。最小连接数是系统启动时连接池所创建的连接数。如果创建过多,则系统启动就慢,但创建后系统的响应速度会很快;如果创建过少,则系统启动的很快,响应起来却慢。这样,可以在开发时,设置较小的最小连接数,开发起来会快,而在系统实际使用时设置较大的,因为这样对访问客户来说速度会快些。最大连接数是连接池中允许连接的最大数目,具体设置多少,要看系统的访问量,可通过软件需求上得到。
如何确保连接池中的最小连接数呢?有动态和静态两种策略。动态即每隔一定时间就对连接池进行检测,如果发现连接数量小于最小连接数,则补充相应数量的新连接,以保证连接池的正常运转。静态是发现空闲连接不够时再去检查。
使用数据库连接池的优势和其工作原理:
1、连接池的优势:
连接池的主要优点有以下三个方面。
一、减少连接创建时间。连接池中的连接是已准备好的、可重复使用的,获取后可以直接访问数据库,因此减少了连接创建的次数和时间。
二、简化的编程模式。当使用连接池时,每一个单独的线程能够像创建一个自己的JDBC连接一样操作,允许用户直接使用JDBC编程技术。
三、控制资源的使用。如果不使用连接池,每次访问数据库都需要创建一个连接,这样系统的稳定性受系统连接需求影响很大,很容易产生资源浪费和高负载异常。连接池能够使性能最大化,将资源利用控制在一定的水平之下。连接池能控制池中的连接数量,增强了系统在大量用户应用时的稳定性。
2、连接池的工作原理
连接池的工作原理主要由三部分组成,分别为连接池的建立、连接池中连接的使用管理、连接池的关闭。
一、连接池的建立。一般在系统初始化时,连接池会根据系统配置建立,并在池中创建了几个连接对象,以便使用时能从连接池中获取。连接池中的连接不能随意创建和关闭,这样避免了连接随意建立和关闭造成的系统开销。Java中提供了很多容器类可以方便的构建连接池,例如Vector、Stack等。
二、连接池的管理。连接池管理策略是连接池机制的核心,连接池内连接的分配和释放对系统的性能有很大的影响。其管理策略是:
>>当客户请求数据库连接时,首先查看连接池中是否有空闲连接,如果存在空闲连接,则将连接分配给客户使用;如果没有空闲连接,则查看当前所开的连接数是否已经达到最大连接数,如果没达到就重新创建一个连接给请求的客户;如果达到就按设定的最大等待时间进行等待,如果超出最大等待时间,则抛出异常给客户。
>>当客户释放数据库连接时,先判断该连接的引用次数是否超过了规定值,如果超过就从连接池中删除该连接,否则保留为其他客户服务。该策略保证了数据库连接的有效复用,避免频繁的建立、释放连接所带来的系统资源开销。
>>连接池的关闭。当应用程序退出时,关闭连接池中所有的连接,释放连接池相关的资源,该过程正好与创建相反。
几种常用的数据库连接池
一、DBCP (Database Connection Pool)
所需jar包:commons-dbcp.jar、commons-pool.jar、commons-collections-3.1.jar
配置
<!-- 配置dbcp数据源 --> <bean id="dataSource2" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <!-- 池启动时创建的连接数量 --> <property name="initialSize" value="5"/> <!-- 同一时间可以从池分配的最多连接数量。设置为0时表示无限制。 --> <property name="maxActive" value="30"/> <!-- 池里不会被释放的最多空闲连接数量。设置为0时表示无限制。 --> <property name="maxIdle" value="20"/> <!-- 在不新建连接的条件下,池中保持空闲的最少连接数。 --> <property name="minIdle" value="3"/> <!-- 设置自动回收超时连接 --> <property name="removeAbandoned" value="true" /> <!-- 自动回收超时时间(以秒数为单位) --> <property name="removeAbandonedTimeout" value="200"/> <!-- 设置在自动回收超时连接的时候打印连接的超时错误 --> <property name="logAbandoned" value="true"/> <!-- 等待超时以毫秒为单位,在抛出异常之前,池等待连接被回收的最长时间(当没有可用连接时)。设置为-1表示无限等待。 --> <property name="maxWait" value="100"/> </bean>
二、C3P0
所需jar包:c3p0-0.9.2.1.jar、mchange-commons-java-0.2.3.4.jar
配置
<!-- 配置c3p0数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="jdbcUrl" value="${jdbc.url}" /> <property name="driverClass" value="${jdbc.driverClassName}" /> <property name="user" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <!--连接池中保留的最大连接数。Default: 15 --> <property name="maxPoolSize" value="100" /> <!--连接池中保留的最小连接数。--> <property name="minPoolSize" value="1" /> <!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 --> <property name="initialPoolSize" value="10" /> <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 --> <property name="maxIdleTime" value="30" /> <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 --> <property name="acquireIncrement" value="5" /> <!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements 属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。 如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0--> <property name="maxStatements" value="0" /> <!--每60秒检查所有连接池中的空闲连接。Default: 0 --> <property name="idleConnectionTestPeriod" value="60" /> <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 --> <property name="acquireRetryAttempts" value="30" /> <!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效 保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试 获取连接失败后该数据源将申明已断开并永久关闭。Default: false--> <property name="breakAfterAcquireFailure" value="true" /> <!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的 时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable 等方法来提升连接测试的性能。Default: false --> <property name="testConnectionOnCheckout" value="false" /> </bean>
三、tomcat 自带的tomcat jdbc pool
Tomcat默认使用的是DBCP数据库连接池,其实从本质上讲,Tomcat是利用Apache Commons DBCP来实现的,只不过把特定的功能集成到了tomcat-dbcp.jar包中。
Tomcat 在 7.0 以前的版本都是使用 commons-dbcp 做为连接池的实现,但是 dbcp 饱受诟病,原因有:
1、dbcp 是单线程的,为了保证线程安全会锁整个连接池
2、dbcp 性能不佳
3、dbcp 太复杂,超过 60 个类
4、dbcp 使用静态接口,在 JDK 1.6 编译有问题
5、dbcp 发展滞后
为此,Tomcat 从 7.0 开始引入一个新的模块:Tomcat jdbc pool
1、tomcat jdbc pool 近乎兼容 dbcp ,性能更高
2、异步方式获取连接
3、tomcat jdbc pool 是 tomcat 的一个模块,基于 tomcat JULI,使用 Tomcat 的日志框架
4、使用 javax.sql.PooledConnection 接口获取连接
5、支持高并发应用环境
6、超简单,核心文件只有8个,比 c3p0 还
7、更好的空闲连接处理机制
8、支持 JMX、支持 XA Connection
9、tomcat jdbc pool 可在 Tomcat 中直接使用,也可以在独立的应用中使用。
配置方法:
方法一、在Tomcat\conf目录下的context.xml文件中Context标签结尾前配置如下内容:
<!--配置oracle数据库的连接池--> <Resource name="jdbc/oracleds" author="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000" username="scott" password="tiger" driverClassName="oracle.jdbc.dirver.OracleDriver" url="jdbc:oracle:thin:@127.0.0.1:1521:ora9" /> <!--配置mysql数据库的连接池, 需要做的额外步骤是将mysql的Java驱动类放到tomcat的lib目录下 maxIdle 连接池中最多可空闲maxIdle个连接 minIdle 连接池中最少空闲maxIdle个连接 initialSize 初始化连接数目 maxWait 连接池中连接用完时,新的请求等待时间,毫秒 username 数据库用户名 password 数据库密码 --> <Resource name="jdbc/mysqlds" auth="Container" type="javax.sql.DataSource" username="root" password="root" maxIdle="30" maxWait="10000" maxActive="100" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/db_blog" />
配置好后需要注意的两个步骤:
1.将对应数据库的驱动类放到tomcat的lib目录下
2.重新启动tomcat服务器,让配置生效
在web应用程序的web.xml中设置数据源参考,如下:
在web-app节点中加入下面内容
<resource-ref> <description>mysql数据库连接池</description> <!-- 参考数据源名字,同Tomcat中配置的Resource节点中name属性值"jdbc/mysqlds"一致 --> <res-ref-name>jdbc/mysqlds</res-ref-name> <!-- 资源类型 --> <res-type>javax.sql.DataSource</res-type> <!-- 权限 --> <res-auth>Container</res-auth> <res-sharing-scope>Shareable</res-sharing-scope></resource-ref>
在Web应用中使用数据源
try { //初始化查找命名空间 Context ctx = new InitialContext(); //参数java:/comp/env为固定路径 Context envContext = (Context)ctx.lookup("java:/comp/env"); //参数jdbc/mysqlds为数据源和JNDI绑定的名字 DataSource ds = (DataSource)envContext.lookup("jdbc/mysqlds"); Connection conn = ds.getConnection(); conn.close(); out.println("<span style='color:red;'>JNDI测试成功<span>"); } catch (NamingException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); }
方法二、在Tomcat的conf/server.xml中配置虚拟目录时配置
在配置虚拟目录时,也就是在配置conf下面的server.xml时,在context标签内添加池配置.在说该方法之前,先说一下,如何用tomcat配置虚拟目录。在tomcat\conf下server.xml中找到
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"></Host>
在其中添加:
<Context path="/website" docBase="F:/myweb" reloadable="true"></Context>
注意:
docBase要改成你的项目目录。
path为虚拟路径,访问时的路径,注意:一定要加“/” debug建议设置为0
reloadable设置为true。
这样重新启动tomcat
实例中如下配置
<Context path="/website" docBase="D:/program files/Tomcat/apache-tomcat-6.0.33/webapps/iblog.war" reloadable="true"></Context>
接下来添加池配置,如下
<!--配置虚拟目录--><Context path="/website" docBase="D:/program files/Tomcat/apache-tomcat-6.0.33/webapps/iblog.war" reloadable="true"> <Resource name="jdbc/mysqlds" auth="Container" type="javax.sql.DataSource" username="root" password="root" maxIdle="30" maxWait="10000" maxActive="100" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/db_blog" /></Context>
方法三、在Web项目中的META-INF目录下新建一个文件context.xml,写入配置
注意:是META-INF目录下,不是WEB-INF目录下
<?xml version='1.0' encoding='utf-8'?><Context> <Resource name="jdbc/mysqlds" auth="Container" type="javax.sql.DataSource" username="root" password="root" maxIdle="30" maxWait="10000" maxActive="100" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/db_blog" logAbandoned="true" /></Context>
方法四、在Tomcat的conf/server.xml中配置
打开tomcat的conf/server.xml文件,找到GlobalNamingResources节点,默认的内容如下
<GlobalNamingResources> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /></GlobalNamingResources>
在该节点中加入相关的池配置信息,如下
<GlobalNamingResources> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> <!--配置mysql数据库的连接池, 需要做的额外步骤是将mysql的Java驱动类放到tomcat的lib目录下 --> <Resource name="jdbc/mysqlds" auth="Container" type="javax.sql.DataSource" username="root" password="root" maxIdle="30" maxWait="10000" maxActive="100" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/db_blog" /> </GlobalNamingResources>
在tomcat的conf/context.xml文件中的节点中加入如下内容
<ResourceLink name="jdbc/mysqlds" global="jdbc/mysqlds" type="javax.sql.DataSource"/>
然后在web项目中的WEB-INF目录下的web.xml中配置
<resource-ref> <description>mysql数据库连接池</description> <!-- 参考数据源名字,同Tomcat中配置的Resource节点中name属性值"jdbc/mysqlds"一致 --> <res-ref-name>jdbc/mysqlds</res-ref-name> <!-- 资源类型 --> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-sharing-scope>Shareable</res-sharing-scope></resource-ref>
同样配置好后,需要重新启动服务器,让配置生效.
- 数据库连接池c3p0和dbcp和tomcat-dbcp
- 数据库连接池c3p0和dbcp
- 数据库连接池DBCP和C3P0
- 数据库连接池c3p0和dbcp
- 数据库连接池DBCP和C3P0
- 数据库连接池c3p0和dbcp
- 数据库连接池c3p0和dbcp
- 数据库连接池 DBCP和c3p0数据库连接池
- 数据库连接池——dbcp和c3p0
- 数据库连接池以及C3P0和DBCP
- 数据库连接池:Dbcp和C3p0学习
- C3P0和DBCP数据库连接池的
- 数据库连接池c3p0/dbcp
- Java框架数据库连接池比较(c3p0,dbcp和proxool)
- Java框架数据库连接池比较(c3p0,dbcp和proxool)
- Java框架数据库连接池比较(c3p0,dbcp和proxool)
- Java框架数据库连接池比较(c3p0,dbcp和proxool)
- Java框架数据库连接池比较(c3p0,dbcp和proxool)
- 激光雷达学习笔记(五)圆弧
- static关键字
- 平衡二叉查找树(AVL)的插入
- 数据结构学习总结
- 手机号定位骗子揭秘,说精准的都是骗子(原创)
- 数据库连接池c3p0和dbcp和tomcat-dbcp
- 关于Scrapy 自定义Spider Middleware中遇到的坑
- <img src 引入base64格式数据 显示图片 >
- 条件阻塞Condition的应用
- Nginx配置proxy_pass转发的/路径问题
- applicationContext.xml配置hibernate 自动生成表失败
- 第6章 子过程
- fiddler网络调试神器(前端)——擦肩而过
- listview的分页