数据库连接池的深入理解

8.数据库连接池的connection都是长连接的,以方便多次调用,多人连续使用。dataSourcePool
9.数据库连接池中的连接,是在你用完之后,返回给数据库连接池的,并不是close()掉,而是返回,以方便下次其他人使用。
10.数据库连接池会自己通过代码用心跳机制,保证随时最小的连接connection数量同时存在,利用发送空数据的方式。
11.我们平常用的数据库连接都是长连接的,因为我们每次都是从数据库连接池中去拿connection的!!!db source里都是长连接!!
12.一个Connection实例,即对应底层一个TCP链接!一个Connection实例,即对应底层一个TCP链接!
13.connection不是线程安全的!Connection不是线程安全的,它在多线程环境中使用时,会导致数据操作的错乱,特别是有事务的情况.connection.commit()方法就是提交事务,你
可以想象,在多线程环境中,线程A开启了事务,然后线程B却意外的commit,这该是个多么纠结的情况.
14.多个线程同用一个connection会不会提高效率,减少多次连接的消耗?答:不会,因为connection里,每个方法都是synchronized,都执行了同步。所以并不会提高效率。
如:
public int executeUpdate(){
synchronized(connection){
//do
}
}
15.菜鸟一般都是两种方法使用connection:1。要么就是只用一个connection,多个线程都用一个connection。2.要么就是每个方法里面创建一个connection,每次调用都创建
一个connection。
这两种都是效率低下的。
因为TCP链接的创建开支是昂贵的,当然DB server所能承载的TCP并发连接数也是有限制的.因此每次调用都创建一个Connection,这是不现实的;所以才有了数据库连接池的出现.

16.数据库连接池中保持了一定数量的connection实例,当需要DB操作的时候"borrow"一个出来,使用结束之后"return"到连接池中,多线程环境中,连接池中的connection实例交替
性的被多个线程使用.

17.数据库连接池,怎样归还connection?
Connection connection = pool.getConnection();
//do
pool.release(connection);//归还资源

18.2. 在使用dataSourcePool的情况下,一个线程中所有的DB操作使用的是同一个connection吗??
比如线程A,依次调用了2个方法,每个方法都进行了一次select操作,那么这两个select操作是使用同一个connection吗?
第一感觉就是: dataSourcePool本身是否使用了threadLocal来保存线程与connection实例的引用关系;如果使用了threadLocal,那么一个线程多次从pool中获取是同一个
connection,直到线程消亡或者调用向pool归还资源..
如果在spring环境中(或者其他ORM矿建中),这个问题需要分2种情况:事务与非事务.
在非事务场景下,一切都很简单,每一次调用,都是从pool中取出一个connection实例,调用完毕之后归还资源,因此多次调用,应该是不同的connection实例.
public List<Object> select(String sql){
Connection connection = pool.getConnection();
//do
pool.release(connection);//归还资源
}
在使用事务的场景下,情况就有所不同,开启一个新事务的同时,就会冲pool中获取一个connection实例,并将transaction和connection互为绑定,即此transaction中只会使用此
connection,此connection此时只会在一个transaction中使用;因此,在此事务中,无论操作了多少次DB,事实上只会是一个connection实例,直到事务提交或者回滚,当事务提交或
者回滚时,将会解除transaction与connection的绑定关系,同时将connection归还到pool中

//开启事务
public TransactionHolder transaction(){
Connection connection = pool.getConnection();
connection.setAutoCommit(false);
return new TransactionHolder(connection);
}

//执行sql
public boolean insert(String sql,TransactionHolder holder){
Connection connection = holder.getConnection();
//do
try{
//doInsert
return true;
}catch(Exception e){
holder.setRollback(true);
}
return false;
}

//提交事务
public void commit(TransactionHolder holder){
Connection connection = holder.getConnection();
connection.commit();
holder.unbind();//解除绑定
pool.release(connection);//归还资源
}


在有事务的情况上,伪代码可能就像上述例子.对于跨DB分布式事务,可能更加的复杂.

1.先打开一定数量的数据库连接,当使用的时候分配给调用者,调用完毕后返回给连接池,注意返回给连接池后这些连接并不会关闭,而是
准备给下一个调用者进行分配。由此可以看出连接池节省了大量的数据库连接打开和关闭的动作,对系统性能提升的益处不言而喻。
2.注意返回给连接池后这些连接并不会关闭
3.注意返回给连接池后这些连接并不会关闭
4.注意返回给连接池后这些连接并不会关闭
5.所以数据库连接池都是长连接,数据库连接池都是长连接。因为一个连接供给很多次调用。一个连接供给多人调用。当然是长连接了。
6.数据库连接池会利用心跳机制,保证连接池中随时都有最小数量的连接connection随时存在,以随时调用。它利用心跳机制,发送少量的空数据保持连接connection不会因不
发送数据而超过timeout,进而挂掉。

7.几个概念:
最小连接--应用启动后随即打开的连接数以及后续最小维持的连接数。

 

本文不问思想借鉴http://blog.csdn.net/xwq911/article/details/49150043 感谢作者

创建一个数据库连接池:

public class SimplePoolDemo {
    //创建一个连接池
    private static LinkedList<Connection> pool = new LinkedList<Connection>(); 
    
    //初始化10个连接
    static{
        try {
            for (int i = 0; i < 10; i++) {
                Connection conn = DBUtils.getConnection();//得到一个连接
                pool.add(conn);
            }
        } catch (Exception e) {
            throw new ExceptionInInitializerError("数据库连接失败,请检查配置");
        }
    }
    //从池中获取一个连接
    public static Connection getConnectionFromPool(){
        return pool.removeFirst();//移除一个连接对象
    }
    //释放资源
    public static void release(Connection conn){
        pool.addLast(conn);
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值