• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

数据库连接池DBCP浅析

mysql 搞代码 4年前 (2022-01-09) 17次浏览 已收录 0个评论

一个典型的关系数据库应用: a. 建立连接 b. 执行数据库操作 c. 关闭连接 其中建立连接可能需要数ms才能完成。对于多并发请求的场景,频繁的建立连接、断开连接可能会成为程序与关系数据库交互的瓶颈。 为此,很多时候,我们使用数据库连接池来复用连接,避免

一个典型的关系数据库应用:
a. 建立连接
b. 执行数据库操作
c. 关闭连接

其中建立连接可能需要数ms才能完成。对于多并发请求的场景,频繁的建立连接、断开连接可能会成为程序与关系数据库交互的瓶颈。
为此,很多时候,我们使用数据库连接池来复用连接,避免频繁的建立连接带来的资源浪费。
DBCP是应用非常广泛的关系数据库连接池,和DBCP类似的有C3p0, Proxool

DBCP依赖commons-pool提供的连接池,其包括两个不同的版本:
a. DBCP 1.4只能运行在JDK1.6(JDBC 4)
b. DBCP 1.3只能运行在JDK 1.4-1.5(JDBC 3)

DBCP相关配置:DBCP configuration
说明:
dataSource: 要连接的 datasource (通常我们不会定义在 server.xml)
defaultAutoCommit: 对于事务是否 autoCommit, 默认值为 true
defaultReadOnly: 对于数据库是否只能读取, 默认值为 false
driverClassName:连接数据库所用的 JDBC Driver Class,
maxActive: 可以从对象池中取出的对象最大个数,为0则表示没有限制,默认为8
maxIdle: 最大等待连接中的数量,设 0 为没有限制 (对象池中对象最大个数)
minIdle:对象池中对象最小个数
maxWait: 最大等待秒数, 单位为 ms, 超过时间会丟出错误信息
password: 登陆数据库所用的密码
url: 连接数据库的 URL
username: 登陆数据库所用的帐号
validationQuery: 验证连接是否成功, SQL SELECT 指令至少要返回一行
removeAbandoned: 是否自我中断, 默认是 false
removeAbandonedTimeout: 几秒后会自我中断, removeAbandoned 必须为 true
logAbandoned: 是否记录中断事件, 默认为 false
minEvictableIdleTimeMillis:大于0 ,进行连接空闲时间判断,或为0,对空闲的连接不进行验证;默认30分钟
timeBetweenEvictionRunsMillis:失效检查线程运行时间间隔,如果小于等于0,不会启动检查线程,默认-1
testOnBorrow:取得对象时是否进行验证,检查对象是否有效,默认为false
testOnReturn:返回对象时是否进行验证,检查对象是否有效,默认为false
testWhileIdle:空闲时是否进行验证,检查对象是否有效,默认为false
initialSize:初始化线程数

DBCP原理
用户使用数据库连接池流程:
a. 从连接池中获取一个连接(如果有已建立空闲的连接,直接获取连接,否则建立新连接)
b. 执行数据库操作
c. 将连接归还给数据库连接池

源码分析(common-dbcp 1.4)

BasicDataSource是用户使用的类,DBCP项目组放出example:

import javax.sql.DataSource;import java.sql.Connection;import java.sql.Statement;import java.sql.ResultSet;import java.sql.SQLException;impo<strong style="color:transparent">来源gaodai#ma#com搞@代~码$网</strong>rt org.apache.commons.dbcp2.BasicDataSource;public class BasicDataSourceExample {    public static void main(String[] args) {        // First we set up the BasicDataSource.        // Normally this would be handled auto-magically by        // an external configuration, but in this example we'll        // do it manually.        //        System.out.println("Setting up data source.");        DataSource dataSource = setupDataSource(args[0]);        System.out.println("Done.");        //        // Now, we can use JDBC DataSource as we normally would.        //        Connection conn = null;        Statement stmt = null;        ResultSet rset = null;        try {            System.out.println("Creating connection.");            conn = dataSource.getConnection();            System.out.println("Creating statement.");            stmt = conn.createStatement();            System.out.println("Executing statement.");            rset = stmt.executeQuery(args[1]);            System.out.println("Results:");            int numcols = rset.getMetaData().getColumnCount();            while(rset.next()) {                for(int i=1;i<=numcols;i++) {                    System.out.print("\t" + rset.getString(i));                }                System.out.println("");            }        } catch(SQLException e) {            e.printStackTrace();        } finally {            try { if (rset != null) rset.close(); } catch(Exception e) { }            try { if (stmt != null) stmt.close(); } catch(Exception e) { }            try { if (conn != null) conn.close(); } catch(Exception e) { }        }    }    public static DataSource setupDataSource(String connectURI) {        BasicDataSource ds = new BasicDataSource();        ds.setDriverClassName("oracle.jdbc.driver.OracleDriver");        ds.setUsername("scott");        ds.setPassword("tiger");        ds.setUrl(connectURI);        return ds;    }    public static void printDataSourceStats(DataSource ds) {        BasicDataSource bds = (BasicDataSource) ds;        System.out.println("NumActive: " + bds.getNumActive());        System.out.println("NumIdle: " + bds.getNumIdle());    }    public static void shutdownDataSource(DataSource ds) throws SQLException {        BasicDataSource bds = (BasicDataSource) ds;        bds.close();    }}This ad is supporting your extension Smooth GesturesTurn off these ads?

用户在new 一个BasicDataSource时,并未真正建立连接池,建立连接是在用户首次使用getConnection获取连接时发生。
getConnection调用CreateDataSouce获取DataSource,其用synchronized修饰,保证同一时刻最多只有一个线程执行该段代码


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:数据库连接池DBCP浅析

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址