简单的数据库连接池写法及要点

来源:互联网 发布:非线性最优化 编辑:程序博客网 时间:2024/05/20 23:30

在和数据库连接方面,大多数应用,都已经不再是需要一次就连接一次,而大多是通过数据库连接池来实现的。

因为数据库连接和销毁消耗性能是很大的,再一个,在一次数据库连接中,你可以做很多次查询或者维护工作,而不仅仅一次。

所以大多数情况下,数据库连接池使我们的首选。

这里主要讲述一个简单的数据库连接示例,其中使用等待超时来构造,在示例中模拟从连接池中获取、使用和释放连接的过程,而

客户端获取连接的过程被设定为等待超时的模式,也就是在一定时间内如果无法获取到可用连接,将会返回客户端一个null。

首先来看一下数据库连接池的定义。他通过构造函数初始化连接的最大上限,通过一个双向队列来维护连接,调用方需要调用fetchConnection(long)

方法来指定多少毫秒内超时获取连接,而releaseConnection(Connection)方法将连接放回池中。

示例代码:

import java.sql.Connection;import java.util.LinkedList;/** * 我开始印象中是,数据库连接池,既会管理在池中空闲的,也会管理正在使用的, * 维护一个状态,事实证明,如果是这样,那代码维护将会变得十分困难。 */public class ConnectionPool {//一个双向数据库连接队列    private LinkedList<Connection> pool = new LinkedList<Connection>();    /**     * 构造方法,初始化数据库连接池     * @param initialSize     */    public ConnectionPool(int initialSize) {        if (initialSize > 0) {            for (int i = 0; i < initialSize; i++) {                pool.addLast(ConnectionDriver.createConnection());            }        }    }    /**     * 释放连接,即将connection放回池中,并且告知因阻塞而等待的连接请求队列。     * @param connection     */    public void releaseConnection(Connection connection) {        if (connection != null) {            synchronized (pool) {                // 添加后需要进行通知,这样其他消费者能够感知到链接池中已经归还了一个链接                pool.addLast(connection);  //队尾入队                pool.notifyAll();            }        }    }    // 在mills内无法获取到连接,将会返回null    public Connection fetchConnection(long mills) throws InterruptedException {        synchronized (pool) {            // 完全超时            if (mills <= 0) {                while (pool.isEmpty()) {    //池中无连接可用,则进入阻塞状态。                    pool.wait();                }                //队头出队                return pool.removeFirst();            } else {                long future = System.currentTimeMillis() + mills;                long remaining = mills;                while (pool.isEmpty() && remaining > 0) {                    pool.wait(remaining);                    remaining = future - System.currentTimeMillis();                }                //如果超时,且仍无可用连接,则返回的result将为null                Connection result = null;                if (!pool.isEmpty()) {                    result = pool.removeFirst();                }                return result;            }        }    }}


具体的说明都在代码注释中了,思想还是不难理解的,一条队列,队列仅仅维护可用的连接,而每个连接无用时,

则由工作线程将其重新放入数据库连接池中。

并且要注意同步,因为可能多个线程同时请求,此时就应该在同步块中进行代码实现。

0 0
原创粉丝点击