• 数据库——“该连接已关闭”问题解决方案


    问题描述:对数据库的增删改查,出现“该链接已关闭”,发生概论不确定,有时成功,有时失败。

    原因:Connection 是线程不安全的,当将Connection设置为全局变量,若有一个线程正将该连接close,而另一线程正在访问,则会出现“该链接已关闭”的错误。

    解决方案:将Connection设置为局部变量,或每次调用时从新开一个连接。(若嫌速度慢,可以考虑使用连接池)。

    修改后的代码:

    package common.DaoImplement;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.NodeList;
    
    import common.DaoInterface.IConnectionDatabase;
    import common.tool.ReaderXmlConfig;
    
    public class ConDatabaseBySqlServerImp implements IConnectionDatabase
    {
        private String driver;
        private String url;
        private String username;
        private String password;
        private Connection con = null;
        private Statement st = null;
        ResultSet rs  = null;
        /**
         * 通过读取配置文件初始化参数
         * ReaderXmlConfig,这是一个单例的类,用于得到Config.xml配置文件
         */
        public void initialize()
        {
            Document doc = ReaderXmlConfig.getInstance();
            NodeList dbs = doc.getElementsByTagName("db");
            Element db = (Element)dbs.item(0);
            String driver = db.getElementsByTagName("driver").item(0).getFirstChild().getNodeValue();
            String url = db.getElementsByTagName("url").item(0).getFirstChild().getNodeValue();
            String username = db.getElementsByTagName("username").item(0).getFirstChild().getNodeValue();
            String password = db.getElementsByTagName("password").item(0).getFirstChild().getNodeValue();
            
            this.driver = driver;
            this.url = url;
            this.username = username;
            this.password = password;
    
        }
        
        /**
         * 构造方法
         * 加载数据库
         */
        public ConDatabaseBySqlServerImp(){
            initialize();
            try {
                Class.forName(driver);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        
        /**
         *对外提高Connection的接口
         *在此没有直接使用上面定义的con,而是重新定义了一个conn,即每次外部调用getConnection()方法,都将返回一个新的连接(注意在使用后关闭)
         *若此处直接是使用con,可能导致多线程并发访问,导致出错。
         */
        @Override
        public  Connection getConnection() {
            Connection conn = null;
            try {
                    conn = DriverManager.getConnection(url, username, password);
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            return conn;
        }
        
        /**
         * 用于内部的使用
         */
        private void getCon()
        {
            if(con == null)
            {
                try {
                    con = DriverManager.getConnection(url, username, password);
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        
        /**
         * 执行查询
         */
        @Override
        public ResultSet executeSql(String sql) {
            getCon();
            try {
                st = con.createStatement();
                rs = st.executeQuery(sql);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return rs;
        }
    
        /**
         * 执行删除,修改等无返回值的语句
         */
        @Override
        public Boolean executeUpdate(String sql) {
            getCon();
            try {
                st = con.createStatement();
                st.executeUpdate(sql);            
            } catch (SQLException e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }
    
        /**
         * 关闭连接
         */
        @Override
        public void closeConnection() {
            try{
                if(rs != null)
                {
                    rs.close();
                    rs = null;
                }
                if(st != null)
                {
                    st.close();
                    st = null;
                }
                if(con != null)
                {
                    con.close();
                    con = null;
                }
            }catch(SQLException e)
            {
                e.printStackTrace();
            }
        }
        
    }
  • 相关阅读:
    行转列问题
    Session对象失效的客户端解决方法
    Spring之依赖注入
    Spring开发入门
    非关系型数据库redis
    Json(JavaScript Object Notation)
    Ajax
    JavaScript框架之JQuery
    Web核心之Filter过滤器
    Web核心练习之分页模块和条件模块(后台代码为主,jsp已经落伍)
  • 原文地址:https://www.cnblogs.com/ITinfo/p/3462782.html
Copyright © 2020-2023  润新知