zoukankan      html  css  js  c++  java
  • Oracle 大最插入数据 一段时间之后变慢问题解决方法

      因为系统业务需要,需要从数据中心导入12年的历史数据到系统。每天平均1000千左右。有一个表有200多个字段,基中还包括几个clob字段。导入方式是用http向服务器一天一天的请求数据。每次请求一天。不能请求太多天,因为服务器请求太多天,有可能返回不了数据。导致失败,Java的JDBC接口写入。每次写数据都是一条一条的写入。刚开始还算顺利,接口过来的数据都能写入进数据库。但问题出现在写入1个月数据左右就开始慢慢的出现卡顿的情况。写入一条记录的数据,有时10几秒,有几几分钟。最坏的时候,就一条数据几个小时还没有写入成功,导致整个同步进程严重拥堵。每次卡死之后,重启数据库服务又可以正常写入。但每次写入一段时候之后,又卡死。

    试过以下方法都不见效:

    1、停止所有的触发器

    2、接收数据表使用nologging表。

    3、分次提交,一次不要只提交一条记录。一次提交一天记录。

    最后在网上找到了解决方法。也是分次提交,但不是使用executeUpdate()执行,而是使用了先addBatch(), 再executeBatch()的方式。

    具体见代码中的:    public int executeBatch(String sql, List<Object[]> params) 方法。

    附操作数据库的代码

    package bh.ojdbc.util;
    
    import java.sql.CallableStatement;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.ResultSetMetaData;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.apache.log4j.Logger;
    
    import bh.getjzdata.Para;
    import bh.util.SetRW;
    import bh.util.Tool;
     
    /**
     * 对jdbc的完整封装
     *
     */
    public class JDBCUtil {
     
        private static Logger logger = Logger.getLogger(JDBCUtil.class);
    	private static  String driver = null;
    	private static  String url = null;
    	private static  String username = null;
    	private static  String password = null;
    	
    	private CallableStatement callableStatement = null;//创建CallableStatement对象      
    	private Connection conn = null;
    	private PreparedStatement pst = null;
    	private ResultSet rst = null;
    	
    /*	static {    
            try {    
                // 加载数据库驱动程序    
                Class.forName(driver);    
            } catch (ClassNotFoundException e) {    
                System.out.println("加载驱动错误");    
                System.out.println(e.getMessage());    
            }    
        } */   
        
    	public JDBCUtil(){
    		this.driver = Para.oracle_driver;
    		this.url = Para.oracle_url;
    		this.username = Para.oracle_userid;
    		this.password = Para.oracle_password;
    	
    	}
    	
    	public JDBCUtil(String driver,String url ,String username,String password) {
    		this.driver = driver;
    		this.url = url;
    		this.username = username;
    		this.password = password;
    	}
    	
        /**  
         * 建立数据库连接  
         * @return 数据库连接  
         */    
        public Connection getConnection() {    
        	try{
            	if (this.conn!=null && !this.conn.isClosed()){
            		return this.conn;
            	}
        	}
        	catch(Exception e){
        		
        	}
            try {    
            	 // 加载数据库驱动程序    
    
                try {
    				Class.forName(driver);
    			} catch (ClassNotFoundException e) {
    				System.out.println("加载驱动错误");    
    	            System.out.println(e.getMessage());  
    				e.printStackTrace();
    				logger.error(Tool.getExceptionDetail(e));
    			} 
                // 获取连接    
            	conn = DriverManager.getConnection(url, username,    
            			password);    
            } catch (SQLException e) {    
                System.out.println(e.getMessage());    
                logger.error(Tool.getExceptionDetail(e));
            }    
            return conn;    
        }    
        
        public int executeUpdate(String sql, Object[] params) { 
        	return executeUpdate(sql,params,true);
        }
        /**  
         * insert update delete SQL语句的执行的统一方法  
         * @param sql SQL语句  
         * @param params 参数数组,若没有参数则为null  
         * @return 受影响的行数  
         */    
        public int executeUpdate(String sql, Object[] params,boolean isCloseAll) {    
            // 受影响的行数    
            int affectedLine = 0;    
                
            try {    
                // 获得连接    
                conn = this.getConnection();  
                if (!isCloseAll && conn.getAutoCommit()){
                	conn.setAutoCommit(false);
                	
                }
                // 调用SQL     
                pst = conn.prepareStatement(sql);    
                    
                // 参数赋值    
                if (params != null) {    
                    for (int i = 0; i < params.length; i++) {    
                    	pst.setObject(i + 1, params[i]);    
                    }    
                }    
                /*在此 PreparedStatement 对象中执行 SQL 语句,
                                              该语句必须是一个 SQL 数据操作语言(Data Manipulation Language,DML)语句,比如 INSERT、UPDATE 或 DELETE 
                                              语句;或者是无返回内容的 SQL 语句,比如 DDL 语句。    */
                // 执行    
                affectedLine = pst.executeUpdate();
               
            } catch (SQLException e) { 
                if (e.getMessage().indexOf("数据重复")<=0){
    	            System.out.println(e.getMessage());    
    	            logger.error(Tool.getExceptionDetail(e));
    	            logger.error(sql);
    	            if (params != null) {    
    	                for (int i = 0; i < params.length; i++) {    
    	                	logger.error(params[i]);    
    	                }    
    	            } 
                }
                try{
                	conn.commit();
                }
                catch(Exception ex){
                	
                }
                //closeAll();
            } finally {   
            	try{
            		 pst.close();
            	}
            	catch(Exception e){
            		
            	}
            	if (isCloseAll){
                // 释放资源    
            		closeAll();    
            	}
            }    
            return affectedLine;    
        }    
          
        
        
        /**  
         * insert update delete SQL语句的执行的统一方法  
         * @param sql SQL语句  
         * @param params 参数数组,若没有参数则为null  
         * @return 受影响的行数  
         */    
        public int executeBatch(String sql, List<Object[]> params) {    
            // 受影响的行数    
            int affectedLine = 0;    
                
            try {    
                // 获得连接    
                conn = this.getConnection();  
              	conn.setAutoCommit(false);
                // 调用SQL     
                pst = conn.prepareStatement(sql);    
                    
                // 参数赋值    
                if (params != null) {
                    for (int i = 0; i < params.size(); i++) {    
                    	Object[] objs = params.get(i);
                        for (int j = 0; j < objs.length; j++) {    
                        	pst.setObject(j + 1, objs[j]);    
                        } 
                        pst.addBatch();
                    }    
                }    
                /*在此 PreparedStatement 对象中执行 SQL 语句,
                                              该语句必须是一个 SQL 数据操作语言(Data Manipulation Language,DML)语句,比如 INSERT、UPDATE 或 DELETE 
                                              语句;或者是无返回内容的 SQL 语句,比如 DDL 语句。    */
                // 执行    
                pst.executeBatch();
               
            } catch (SQLException e) { 
            	//如果出现异常。重新执行单个插入。
            	try{
            		conn.rollback();
            	}
            	catch(Exception ex){
            		
            	}
                if (params != null) {
                    for (int i = 0; i < params.size(); i++) {    
                      	this.executeUpdate(sql, params.get(i), false);
                   }    
                }           	
    
            } finally {   
            	try{
            		 pst.close();
            	}
            	catch(Exception e){
            		
            	}
            	closeAll();
            }    
            return affectedLine;    
        }    
        
        /**  
         * SQL 查询将查询结果直接放入ResultSet中  
         * @param sql SQL语句  
         * @param params 参数数组,若没有参数则为null  
         * @return 结果集  
         */    
        private ResultSet executeQueryRS(String sql, Object[] params) {    
            try {    
                // 获得连接    
                conn = this.getConnection();    
                    
                // 调用SQL    
                pst = conn.prepareStatement(sql);    
                    
                // 参数赋值    
                if (params != null) {    
                    for (int i = 0; i < params.length; i++) {    
                    	pst.setObject(i + 1, params[i]);    
                    }    
                }    
                    
                // 执行    
                rst = pst.executeQuery();    
        
            } catch (SQLException e) {    
                System.out.println(e.getMessage());    
                logger.error(Tool.getExceptionDetail(e));
            }     
        
            return rst;    
        }    
            
        /**  
         * SQL 查询将查询结果:一行一列  
         * @param sql SQL语句  
         * @param params 参数数组,若没有参数则为null  
         * @return 结果集  
         */    
        public Object executeQuerySingle(String sql, Object[] params) {    
            Object object = null;    
            try {    
                // 获得连接    
                conn = this.getConnection();    
                    
                // 调用SQL    
                pst = conn.prepareStatement(sql);    
                    
                // 参数赋值    
                if (params != null) {    
                    for (int i = 0; i < params.length; i++) {    
                    	pst.setObject(i + 1, params[i]);    
                    }    
                }    
                    
                // 执行    
                rst = pst.executeQuery();    
        
                if(rst.next()) {    
                    object = rst.getObject(1);    
                }    
                    
            } catch (SQLException e) {    
                System.out.println(e.getMessage());
                logger.error(Tool.getExceptionDetail(e));
                
            } finally {    
                closeAll();    
            }    
        
            return object;    
        }    
        
        /**  
         * 获取结果集,并将结果放在List中  
         *   
         * @param sql  SQL语句  
         *         params  参数,没有则为null   
         * @return List  
         *                       结果集  
         */    
        public List<Object> excuteQuery(String sql, Object[] params) {    
            // 执行SQL获得结果集    
            ResultSet rs = executeQueryRS(sql, params);    
                
            // 创建ResultSetMetaData对象    
            ResultSetMetaData rsmd = null;    
                
            // 结果集列数    
            int columnCount = 0;    
            try {    
                rsmd = rs.getMetaData();    
                    
                // 获得结果集列数    
                columnCount = rsmd.getColumnCount();    
            } catch (SQLException e1) {    
                System.out.println(e1.getMessage());    
                logger.error(Tool.getExceptionDetail(e1));
            }    
        
            // 创建List    
            List<Object> list = new ArrayList<Object>();    
        
            try {    
                // 将ResultSet的结果保存到List中    
                while (rs.next()) {    
                    Map<String, Object> map = new HashMap<String, Object>();    
                    for (int i = 1; i <= columnCount; i++) {    
                        map.put(rsmd.getColumnLabel(i), rs.getObject(i));    
                    }    
                    list.add(map);//每一个map代表一条记录,把所有记录存在list中    
                }    
            } catch (SQLException e) {    
                System.out.println(e.getMessage());   
                logger.error(Tool.getExceptionDetail(e));
            } finally {    
                // 关闭所有资源    
                closeAll();    
            }    
        
            return list;    
        }    
            
        /**  
         * 存储过程带有一个输出参数的方法  
         * @param sql 存储过程语句  
         * @param params 参数数组  
         * @param outParamPos 输出参数位置  
         * @param SqlType 输出参数类型  
         * @return 输出参数的值  
         */    
        public Object excuteQuery(String sql, Object[] params,int outParamPos, int SqlType) {    
            Object object = null;    
            conn = this.getConnection();    
            try {    
                // 调用存储过程    
            	// prepareCall:创建一个 CallableStatement 对象来调用数据库存储过程。
                callableStatement = conn.prepareCall(sql);    
                    
                // 给参数赋值    
                if(params != null) {    
                    for(int i = 0; i < params.length; i++) {    
                        callableStatement.setObject(i + 1, params[i]);    
                    }    
                }    
                    
                // 注册输出参数    
                callableStatement.registerOutParameter(outParamPos, SqlType);    
                    
                // 执行    
                callableStatement.execute();    
                    
                // 得到输出参数    
                object = callableStatement.getObject(outParamPos);    
                    
            } catch (SQLException e) {    
                System.out.println(e.getMessage());    
                logger.error(Tool.getExceptionDetail(e));
            } finally {    
                // 释放资源    
                closeAll();    
            }    
                
            return object;    
        }    
        
        /**  
         * 关闭所有资源  
         */    
        public  void closeAll() {    
            // 关闭结果集对象    
            if (rst != null) {    
                try {   
                	if (!rst.isClosed()){
                		rst.close();    
                	}
                } catch (SQLException e) {    
                    System.out.println(e.getMessage());    
                }    
            }    
        
            // 关闭PreparedStatement对象    
            if (pst != null) {    
                try {    
                	if (!pst.isClosed()){
                		pst.close();    
                	}
                } catch (SQLException e) {    
                    System.out.println(e.getMessage()); 
                    logger.error(Tool.getExceptionDetail(e));
                }    
            }    
                
            // 关闭CallableStatement 对象    
            if (callableStatement != null) {    
                try {    
                    callableStatement.close();    
                } catch (SQLException e) {    
                    System.out.println(e.getMessage());    
                    logger.error(Tool.getExceptionDetail(e));
                }    
            }    
        
            // 关闭Connection 对象    
            if (conn != null) {    
                try {    
                	if(!conn.getAutoCommit()&&!conn.isClosed()){
                		conn.commit();
                	}
                	if(!conn.isClosed()){
                		conn.close();
                	}
                } catch (SQLException e) {    
                    System.out.println(e.getMessage());   
                    logger.error(Tool.getExceptionDetail(e));
                }    
            }       
        }    
    }
    

      

  • 相关阅读:
    ECMAScript 引用类型Object 对象
    jQuery Form Plugin
    在 PHP5 中使用 DOM 控制 XML
    JavaScript encodeURI()和encodeURIComponent() 函数
    程序员进阶的建议:多看、多写、多交流
    jQuery 取 css zindex 值在各种浏览器中的返回值
    XPath 语法教程(Tutorial_2)
    使用 strpos 需要注意 === 运算符
    关于代码开发规范和原则
    PHP 编写大型网站问题集
  • 原文地址:https://www.cnblogs.com/KevinMO/p/14139225.html
Copyright © 2011-2022 走看看