Java Web 架构系列 知识(一) 数据库连接池

一、初始数据库连接

 刚开始学习Java操作数据库时,在学生时代使用原生jdbc做连接数据库动作,对每个数据库操作业务,做手工的一系列动作。

(1) JDBC驱动注册

(2) 建立数据库连接

(3) 建立数据库操作句柄

(4) 使用ResultSet去执行句柄的SQL语句

(5) 对ResultSet做后续取值组装动作

(6) 释放数据库连接

代码实例如下:

    /**
     * 测试连接,无连接池
     */
    private void testConnOrigin(){
        try{
            long start = System.currentTimeMillis();
            // 1. static block register jdbc.driver
            Class.forName("com.mysql.jdbc.Driver");

            // 2. using user/pwd to connect mysql
            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/du?user=root&password=admin");

            long end = System.currentTimeMillis();

            System.out.println("conn-time: " + (end - start));
            // 3. declare handler
            Statement state = conn.createStatement();

            // 4. execute sql to store in resultSet
            String sql = "select * from server";
            ResultSet result = state.executeQuery(sql);

            // 5. opr resultSet
            while(result.next()){
                System.out.println(result.getString("id"));
            }
            conn.close();
        }catch(Exception e){
            System.out.println(e.toString());
        }finally {

        }

    }
其中测试创建数据库连接的时间长度,大概在:conn-time: 669ms, 不同测试机环境可能会有不同误差,但建立数据库连接和关闭数据库连接的确会消耗时间和程序性能。
数据库连接消耗什么资源:
(1) 建立数据库连接时: 三次握手建立TCP连接
(2) 校验用户名密码等,需要发送认证报文
(3) 查询开始时,需要设置连接的变量,如字符设置等
(4) 关闭数据库连接时:四次挥手断开TCP连接
(5) 持有过多的数据库连接,对数据库客户端和服务器端的内存会造成较大消耗

二、数据库连接池
1. 核心思想:
(1) 连接复用:避免重复建立关闭数据库连接
(2) 封装JDBC:操作统一,简单化
2. 解决方案:
(1) 资源池、容器类:存储管理所有数据库连接
(2) 分配、释放策略:


3. 配置策略:(如何配置?)
(1)初始连接数:过小则会后续创建过多连接,过大则启动创建时间长
(2)最大连接数:
4. 关键点:
(1) 引用计数:
原理:每个连接被使用,引用计数+1,超过最大引用计数大小,销毁该连接。
原因:每个数据库连接在使用操作时,都会使用一大块内存,超过一定次数时,需要销毁该连接,释放这块内存
(2) 两极连接池:
(3) 事务管理:
原理:每个事务独占一个连接
原因:多个事务公用一个connection,会出现许多ACID的麻烦
(4) 统一对外操作接口
(5) 数据库连接线程安全
原理:可使用synchronized、BlockQueue、ThreadLocal、CopyOnWriteArrayList等线程安全或线程安全容器来保证
5. 数据库连接池基本原理实现
解决数据库连接和关闭数据库连接的时间消耗和性能消耗,比较好的方式就是数据库连接池,基本原理很简单:
(1) 在程序开始时,创建最小数据库连接数个数据库连接,放在容器类如BlockQueue中。
(2) 需要使用数据库时,调用getConnection,从连接池中取出空闲的connection对象,进行使用。(涉及分配释放策略)
(3) 使用完毕后,将该数据库连接归还数据库连接池,达到数据库连接复用作用。
6. 具体代码:略




猜你喜欢

转载自blog.csdn.net/blueskypan/article/details/77601422