zoukankan      html  css  js  c++  java
  • 数据库连接池dataesoruce pool深入理解

    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);
        }
    }
  • 相关阅读:
    日期正则表达式yyyyMMdd
    Markdown语法
    su: Authentication failure问题
    Git初始配置
    layui的layer.open()方法查看缩略图 原图缩放
    入驻博客园三年
    php学习笔记之动态生成一组单选button
    opencv直方图拉伸
    c++ 中const的使用
    LeetCode131:Palindrome Partitioning
  • 原文地址:https://www.cnblogs.com/panxuejun/p/6402890.html
Copyright © 2011-2022 走看看