mysql数据库Too many connections 错误的解决过程记录

在做一个注册页面的时候,要用到ajax异步校验用户输入的信息是否正确,还得做用户名查重工作,所以需要频繁的访问数据库。我用的c3p0的一个操作数据库的utils是我自己在我看完学习视频之后做的,我做的utils和视频中做的不同的是:视频中做的utils是注册驱动、设置ComboPooledDataSource和获得connection分开,我做的是一个getConnection方法一步到位。平常使用数据库频率不高也就没发现什么问题,直到现在东窗事发......

昨天出现了错误Too many connections ;我还纳闷我每次用完连接都会关闭,为什么会Too many connections ...

使用命令  show full processlist; 发现居然有上2万个sleep连接,

一停止程序运行又只剩下一个链接(就是本机连接),

检查了一下代码,发现“创建连接池”和“取用连接”和“关闭连接”代码放在一起,导致了这样一个工作流程:

一个用户访问----->创建一个链接池(20个连接)--->取用一个连接----->关闭一个链接;

于是多次访问(多个用户访问)的时候就创建了多个连接池,但每一个用户都只关闭了其中一个链接,留下一堆链接;

比如,30个用户访问,每个用户访问都创建一个20个连接的连接池,总共创建了600个链接,但30个用户全部访问结束时,总共才关闭了30个链接,留下570个链接。

用户越来越多,导致无用的链接越来越多,所以就有了Too many connections 

 

正确的使用数据库做法是:先设置ComboPooledDataSource;再调用一个链接,而且每次调用都要关闭;

参考以下程序(测试程序,不是注册程序)

public class C3p0 {
    ComboPooledDataSource dataSource = new ComboPooledDataSource();  
    @Test
    public void name() throws Exception {//1000次测试
        setConnection();
        for(int i=0;i<1000;i++){
            Thread.sleep(200);
            operateDatabase();
            System.out.println(i);
        }
    }
    
    
    /** 
     * 演示c3p0的使用方法 
     * @project_name Day11    
     * @class_name C3P0Demo    
     * @author Dovinya 
     * @data 2014-8-27 下午07:57:42    
     * @version 1 
     * @notes 
     */  
 
    public void setConnection() {//设置ComboPooledDataSource
        try {
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/kxpro");  
        dataSource.setUser("root");  
        dataSource.setPassword("514079");  
        dataSource.setMinPoolSize(5);//连接池最小连接数
        dataSource.setInitialPoolSize(20);//连接池创建时连接数
        dataSource.setMaxPoolSize(80);//连接池最大连接数
        dataSource.setAcquireIncrement(5);//链接用完时创建的连接数
        dataSource.setNumHelperThreads(5);//多线程执行,提升性能
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.out.println("没找到驱动");
        }  
    }
          
        @Test
        public void operateDatabase() {  //使用链接
            Connection conn =null;  
            PreparedStatement ps = null;  
            ResultSet rs = null;  
            try {  
//              Class.forName("com.mysql.jdbc.Driver");  
//              conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day11", "root", "123");  
//              ps = conn.prepareStatement("select * from account");  
             
                conn =  dataSource.getConnection();
                ps = conn.prepareStatement("select * from login");  
                rs = ps.executeQuery();  
                while(rs.next()){
                    System.out.println(rs.getString("username"));
                }
                  
                while(rs.next()){  
                    String name = rs.getString("name");  
                    System.out.println(name);  
                }  
                  
            } catch (Exception e) {  
                e.printStackTrace();  
            }finally{  
                if(rs!=null){  
                    try {  
                        rs.close();  
                    } catch (SQLException e) {  
                          
                        e.printStackTrace();  
                    }finally{  
                        rs=null;  
                    }  
                }  
                  
                if(ps!=null){  
                    try {  
                        ps.close();  
                    } catch (SQLException e) {  
                          
                        e.printStackTrace();  
                    }finally{  
                        ps=null;  
                    }  
                }  
                  
                if(conn!=null){  
                    try {  
                        conn.close(); 
                        System.out.println("conn yiguanbi");
                    } catch (SQLException e) {  
                          
                        e.printStackTrace();  
                    }finally{  
                        conn=null;  
                    }  
                }             
              
            }  
        }  
          
    
}

 

最重要的是ComboPooledDataSource 要作为成员变量,只执行一次,创建连接池,以后用户只需取用即可 

 

posted @ 2017-07-30 23:06  sovagxa&静默  阅读(1789)  评论(1编辑  收藏  举报