引言


setAutoCommit方法用一句话说就是用来保持事务完整性,一个系统的更新操作可能涉及多张表,这个时候,就需要用多个Sql语句来实现,实际上我觉得这个东西就是用来实现事务的。


当我们进行多条数据进行增删改的时候,一旦在一句sql中出现了错误,就会出现有部分数据已经成功,而后面的数据就没有办法执行,这个时候,就会出现脏数据。


因此我们使用setAutoCommit方法,这个方法有一个参数,参数值为Boolean,当true的时候可启用自动提交模式,false可禁用该模式。


注释中有一句话是这样说的:Newlycreated Connection objects are in auto-commit mode by default, which means thatindividual SQL statements are committed automatically when the statement iscompleted. To be able to group SQL statements intotransactions and commit them or roll them back as a unit, auto-commit must bedisabled by calling the method setAutoCommit with false as its argument. Whenauto-commit is disabled, the user must call either the commit or rollbackmethod explicitly to end a transaction.翻译过来是这样的:如果连接处于自动提交模式下,则其所有的SQL语句将作为单个事务运行并提交。否则,其SQL语句将作为事务组,直到调用Commit方法或rollback方法为止。默认情况下,新连接处于自动提交模式。


简单来说,


下面的代码:


<span style="font-size:18px;">int[] result =null;
	    con.setAutoCommit(false);   
	    Statement stmt =con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,   
	                                       ResultSet.CONCUR_READ_ONLY);   
	    String[] SqlString= null;
	    for(String strvalue : SqlString){   	    	
	       stmt.execute(strvalue);   
	    }   
	    con.commit(); 
	    return result;</span>


可以看到,如果代码没有出错,弹幕我们就执行Commit没有问题,但是一旦出错,我们应该执行数据的rollback,但是该代码没有进行处理,这个时候,就会出现锁,将表锁住,这个锁就没有机会释放。


因此,我们应该这样写:


<span style="font-size:18px;">    	 boolean result = false;
    	 try{
		    con.setAutoCommit(false);   
		    Statement stmt =con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,   
		                                       ResultSet.CONCUR_READ_ONLY);   
		    String[] SqlString= null;
		    for(String strvalue : SqlString){   	    	
		    	result = stmt.execute(strvalue);   
		    }   
		    con.commit(); 
    	 }catch(Throwable e){
             if(con!=null){
                 try {
                     con.rollback();
                 } catch (SQLException e1) {
                     e1.printStackTrace();
                 }
             }
    	 }finally{
             if(con!=null){
                 try {
                     con.close();
                 } catch (SQLException e) {
                     e.printStackTrace();
                 }
             }
    	 }
	    return result;</span>

因此,我们一定不要小看了这个问题,这个问题一旦出现,性能就会收到很大的影响。


如果我们将SQL语句作为单个事务进行处理的话:


<span style="font-size:18px;">  /**
     * 使用PreparedStatement加批量的方法
     * @return
     */
    public int[] executeUpdateMore(){    
    	int[] result=null;    	
    	try{   
    		PreparedStatement prest =con.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
    	     for(List sqlValueString : sqlValue){    	    
    	    	 for(int i=0;i<sqlValueString.size();i++){
    	     		try {
    	     			prest.setObject(i+1,sqlValueString.get(i));
    	 			} catch (SQLException e) {
    	 				// TODO Auto-generated catch block
    	 				e.printStackTrace();
    	 			}    	 				   	 			
    	     	}
    	    	prest.addBatch();
    	     }
    	     prest.executeBatch();  
    	 /*    con.commit();*/   
    	     this.closeAll(con, prest, null);
    	} catch (SQLException ex){   
    	  Logger.getLogger(Dbhelper.class.getName()).log(Level.SEVERE, null,ex);   
    	} 
    	return result;       
    } </span>

如果我们将SQL语句作为事务组来处理的话,我们就要这样写:


<span style="font-size:18px;">    /**
     * 使用PreparedStatement加批量的方法,strvalue:
     * "INSERT INTOadlogs(ip,website,yyyymmdd,hour,object_id) VALUES('192.168.1.3','localhost','20081009',8,'23123')"
     * @return
     * @throws SQLException 
     */
    public boolean executeUpdateMoreNotAuto() throws SQLException{   
    	
    	 boolean result = false;
    	 try{
		    con.setAutoCommit(false);   
		    Statement stmt =con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,   
		                                       ResultSet.CONCUR_READ_ONLY);   
		    String[] SqlString= null;
		    for(String strvalue : SqlString){   	    	
		    	result = stmt.execute(strvalue);   
		    }   
		    con.commit(); 
    	 }catch(Throwable e){
             if(con!=null){
                 try {
                     con.rollback();
                 } catch (SQLException e1) {
                     e1.printStackTrace();
                 }
             }
    	 }finally{
             if(con!=null){
                 try {
                     con.close();
                 } catch (SQLException e) {
                     e.printStackTrace();
                 }
             }
    	 }
	    return result;
    }</span>

结束语:


一定要记住处理完之后要提交或者回滚奥!




Logo

更多推荐